meetar
meetar

Reputation: 7611

socket.io-stream error: stream has already been sent

I'm attempting to pipe binary data from one client's 256x256 canvas to a canvas on another client, through a node.js server with socket.io-stream.

In my server:

ss(socket).on('blatin', function(stream, data) {
    var outgoingstream = ss.createStream();
    ss(remote).emit('blatout', outgoingstream);
    stream.pipe(outgoingstream);
});

In the source client:

canvas.addEventListener("mousemove", function(e){
    sendBlat();
});

var socket = io();
var stream = ss.createStream();
var imageBuffer = new ss.Buffer(256*256*4);

function sendBlat() {
    console.log('blatting'); 
    // send buffer to the server
    imageBuffer.set(ctx.getImageData(0,0,canvas.width,canvas.height).data);
    stream.write(imageBuffer);
    ss(socket).emit('blatin', stream);
    return false;
}

And in the destination client:

ss(socket).on('blatout', function(stream, data)
    stream.on('data', function(chunk) {
        imageData.data.set(new Uint8ClampedArray(chunk));
        ctx.putImageData(imageData,0,0);
    });
});

… this works, but is quite slow, and in my source client's console I see this error repeated over and over:

socket.io-stream.js:794 Uncaught Error: stream has already been sent.

So I'm clearly not handling the stream properly. What step(s) am I missing?

Notes:

Upvotes: 2

Views: 1401

Answers (1)

meetar
meetar

Reputation: 7611

You're re-emitting and re-pipeing the stream every time you write to it, and you don't need to do that!

The socket.io-stream examples assume that you're uploading new files (and therefore new streams) every time, each of which need a new emit() to get to the server, and a new pipe() to go anywhere else.

But in your case, you can simply re-write to the same stream over and over, which means you only need to emit() once from the source client, and pipe() once on the server.

Server:

var outgoingstream = ss.createStream();
ss(remote).emit('blatout', outgoingstream);
ss(socket).on('blatin', function(stream, data) {
  stream.pipe(outgoingstream);
});

Source client:

var socket = io();
var stream = ss.createStream();
ss(socket).emit('blatin', stream);

var imageBuffer = new ss.Buffer(256*256*4);
function sendBlat() {
    imageBuffer.set(ctx.getImageData(0,0,canvas.width,canvas.height).data);
    stream.write(imageBuffer);
    return false;
}

Upvotes: 1

Related Questions