2016-11-29 45 views
0

我試圖通過一個node.js服務器與socket.io-stream將二進制數據從一個客戶端的256x256畫布管道傳輸到另一個客戶端上的畫布。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. 

所以我顯然沒有正確處理流。我錯過了哪些步驟?

注:

  • 這很容易填充緩衝區,看着它慢慢地空出到目標客戶。 - 服務器過載也很容易,直到它停止響應。
  • 節流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; 
}