【问题标题】:Why can't this socket be accessed from JavaScript web worker?为什么不能从 JavaScript web worker 访问这个套接字?
【发布时间】:2016-09-02 04:44:04
【问题描述】:

我想使用 socket.io 将音频缓冲区从 JavaScript 流式传输到我的烧瓶服务器。但是当我想从音频回调函数中使用它时,套接字实例是“未定义的”。

在这段代码中,我在主线程中的套接字实例是“套接字”。每次从麦克风接收到新缓冲区时,工作人员都会调用函数“记录”。

但 socket.emit 总是给我:

Uncaught ReferenceError: socket is not definedrecord @ 斑点:http://localhost:7777/400a58bc-b64f-4c66-9bb1-65a28bf9bfba:39onmessage @blob:http://localhost:7777/400a58bc-b64f-4c66-9bb1-65a28bf9bfba:15

如何从工作人员中正确访问套接字?

在主线程中,我有套接字对象和 web worker 在 postMessage 中调用的方法:

var socket = io.connect('http://' + document.domain + ':'+location.port);
socket.on('connect', function() {
  socket.emit('my event', {data: 'I\'m connected!'});
});

...

function record(inputBuffer){
  var buf = inputBuffer[0]
  ///////HERE THE socket CANNOT BE FOUND, WHY??
  socket.emit('audio event',{data : buf})
}

在 web worker 线程中,postMessage 调用 'record' 方法:

this.onmessage = function(e){
  switch(e.data.command){
    case 'record':
      /////HERE THE 'record' FUNCTION IS CALLED IN THE MAIN THREAD
      record(e.data.buffer);
      break;
  }
};

...

(function(window){

  var Recorder = function(source, cfg){
    this.context = source.context;
    if(!this.context.createScriptProcessor){
       this.node = this.context.createJavaScriptNode(bufferLen, 2, 2);
    } else {
       this.node = this.context.createScriptProcessor(bufferLen, 2, 2);
    }
    var currCallback;

    this.node.onaudioprocess = function(e){
      ////THIS IS THE CALLBACK FROM MICROPHONE HARDWARE
      worker.postMessage({
        command: 'record',
        buffer: [
          e.inputBuffer.getChannelData(0),
          e.inputBuffer.getChannelData(1)
        ]
      });
    }

    this.record = function(){
      recording = true;
    }

    worker.onmessage = function(e){
      var blob = e.data;
      currCallback(blob);
    }

  window.Recorder = Recorder;

})(window);

【问题讨论】:

  • webWorker 中的代码无法从主线程访问任何变量,反之亦然。我无法在您的问题中的代码中分辨出哪些代码在主 JS 线程中,哪些代码在 webWorker 中,但是您不能在两者之间共享变量。正如您似乎已经知道的那样,您可以在两者之间发送消息,并且可以随消息发送数据副本,但您不能在两者中访问相同的变量。
  • 我想补充一点,您也无法从您的工作人员中访问任何 DOM 元素。所以就像 jfriend00 说的,通信完全发生在主 JS 和 worker 之间发送和接收的消息上。不过,您可以在消息中发布本机 JS 对象。也只是 vanilla JS,没有 Jquery 或您可能在您的工作人员中使用的任何东西。
  • 我想我可能将“本机对象”与更一般的东西混淆了。我说的是var variables = {name: 'abc', URL: 'http://.....'};
  • 我编辑了,哪个部分在主线程中,哪个在worker中。任何想法如何正确访问套接字? @jfriend00

标签: javascript audio socket.io web-worker flask-socketio


【解决方案1】:

如果您的套接字位于主线程中,则无法从 webWorker 访问它。这是 webWorkers 的限制。您不能在主线程和 webWorker 之间共享变量。由于并发问题而存在此限制。

您的选择是:

  1. 在 webWorker 中创建 webSocket,以便socket 变量存在于 webWorker 中并且可以在那里使用。

  2. 当你想从 webWorker 中向 webSocket 发送数据时,向主线程发送一条带有数据作为参数的消息,要求它在 webSocket 上发送数据并让主线程进行实际发送.因此,所有在 webSocket 上的发送都将留在主线程中。

【讨论】:

    猜你喜欢
    • 2021-07-01
    • 2013-04-13
    • 2011-03-20
    • 1970-01-01
    • 2012-09-20
    • 2014-09-26
    • 2013-10-20
    • 1970-01-01
    相关资源
    最近更新 更多