2016-11-29 1 views
0

Я пытаюсь передать двоичные данные из холста 256x256 одного клиента на холст на другом клиенте через сервер node.js с socket.io-stream.Ошибка socket.io-stream: поток уже отправлен

В моем сервере:

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

В клиенте источник:

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

И в клиенте назначения:

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

... это работает, но довольно медленно, и в консоли моего исходного клиента я вижу, что эта ошибка повторяется снова и снова:

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

Таким образом, я явно не обрабатываю поток должным образом. Какие шаги мне не хватает?

Примечания:

  • Это очень легко, чтобы заполнить буфер и смотреть его медленно выплескивать в клиент назначения. - Также очень легко перегрузить сервер, пока он не перестанет отвечать.
  • Throttling sendBlat() не помогает.
  • Отправка холста ImageData - это цель, а не приложение для рисования - приложение является просто доказательством концепции.
  • MacOS/Chrome.

ответ

0

Вы переизбираете и перетаскиваете поток каждый раз, когда вы пишете на него, и вам не нужно это делать!

В примерах socket.io-stream предполагается, что вы загружаете новые файлы (и, следовательно, новые потоки) каждый раз, каждый из которых нуждается в новом emit(), чтобы добраться до сервера, и новый pipe(), чтобы отправиться куда-нибудь еще.

Но в вашем случае вы можете просто перезаписать один и тот же поток снова и снова, а это значит, что вам нужно только один раз указать emit() у исходного клиента и pipe() один раз на сервере.

Сервер:

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

Источник клиент:

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