0

I want to stream audio buffers from JavaScript to my flask server, using socket.io. But the socket instance is 'undefined' when I want to use it from within the audio callback function.

In this code, my socket instance in the main thread is 'socket'. The function 'record' is called from the worker every time a new buffer is received from the microphone.

But the socket.emit always gives me:

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

How can I access the socket correctly from within the worker?

In the main thread, I have the socket object and the method that is called in postMessage from the web worker:

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})
}

In the web worker thread, postMessage calls the 'record' method:

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);
jfriend00
  • 683,504
  • 96
  • 985
  • 979
user2212461
  • 3,105
  • 8
  • 49
  • 87
  • 2
    Code in a webWorker does not have access to ANY variables from the main thread or vice versa. I can't tell in the code you have in your question which code is in the main JS thread and which code is in a webWorker, but you can't share variables between the two. As you appear to know already, you can send messages between the two and you can send copies of data with the message, but you can't access the same variable in both. – jfriend00 Sep 02 '16 at 05:15
  • 1
    I'd like to add that you also cannot access any DOM element from within your worker. So like jfriend00 said, communication happens entirely over sent and received messages between main JS and worker. You CAN post native JS objects in your messages though. Also just vanilla JS, no Jquery or anything you might be working with in your worker. – Aurel Engle Engelmann Sep 02 '16 at 09:53
  • 1
    I think I may have "native object" confused with something more general. I'm talking about things like `var variables = {name: 'abc', URL: 'http://.....'};` – Aurel Engle Engelmann Sep 02 '16 at 09:58
  • I edited, which part is in the main thread and which in the worker. Any ideas how to access the socket correctly? @jfriend00 – user2212461 Sep 02 '16 at 12:52

1 Answers1

0

If your socket is in the main thread, you can't access it from the webWorker. That's a limitation of webWorkers. You cannot share variables between main thread and webWorker. This limitation exists because of concurrency issues.

Your choices here would be:

  1. Create the webSocket in the webWorker so the socket variable exists in the webWorker and can be used there.

  2. When you want to send data to the webSocket from within the webWorker, send a message to the main thread with data as an argument asking it to send the data on the webSocket and have the main thread do the actual sending. So, all sending on the webSocket would stay in the main thread.

jfriend00
  • 683,504
  • 96
  • 985
  • 979