如何通过 socket.io 将数据流式传输到客户端 [英] How to stream data over socket.io to client
问题描述
我让 socket.io 从服务器向客户端发送一个基本对象.这一点工作正常.
现在想从服务器向客户端发送流,使用
您使用 socket.emit
是错误的,您将 ACK 回调传递给客户端而不是流.看看 socket.emit
signature :socket.emit(eventName[, ...args][, ack])
.
你可能想要像
socket.emit('blockchainOps', client.blockchain.getBlockStream());
但是,我认为普通套接字 io 不支持像这样传递 Stream.要将流向下传输到客户端,您可以使用 socketio-stream.它看起来像这样:
var ss = require('socket.io-stream');var 流 = ss.createStream();ss(socket).emit('blockchainOps', 流);client.blockchain.getBlockStream().pipe(stream);
在客户端上,您应该能够像这样读取流:
<script src="socket.io-stream.js"></script>...ss(socket).on('blockchainOps', function(stream) {var binaryString = "";stream.on('数据', 函数(数据) {for(var i=0;i<data.length;i++) {binaryString+=String.fromCharCode(data[i]);}});stream.on('end', function(data) {控制台日志(二进制字符串);binaryString = "";});});
I have socket.io sending a basic object from server to client. This bit works fine.
Now want to send a stream from server to client, using event-stream (specifically the results of a block-chain query). I am getting unexpected results in the browser console..
var io = require('socket.io')(server);
var dsteem = require('dsteem')
var es = require('event-stream')
var util = require('util')
var client = new dsteem.Client('https://api.steemit.com')
var stream = client.blockchain.getBlockStream()
/* This sends results to stdout, fine
io.on('connection', function(socket){
stream.pipe(es.map(function(block, callback) {
callback(null, util.inspect(block) + '\n')
})).pipe(process.stdout);
// And this sends a simple object to the client
socket.emit('blockchainOps', {"Foo!":"Doo!"} );
});
*/
// Putting both together sends strange connection data to client
io.on('connection', function(socket){
socket.emit('blockchainOps', function() {
stream.pipe(es.map(function(block, callback) {
callback(null, util.inspect(block) + '\n');
}))
})
});
What I get in the client console appears to be some kind of TCP socket function,
ƒ (){if(!n){n=!0;var r=a(arguments);u("sending ack %j",r),e.packet({type:i.ACK,id:t,data:r})}}
Can anyone help me understand what's going on and what I'm doing wrong?
== EDIT UPDATE ==
As suggested in comments, I've tried socket.io-stream to augment event-stream.
var es = require('event-stream')
var util = require('util')
var ss = require('socket.io-stream');
var stream = ss.createStream();
io.on('connection', function(socket){
ss(socket).emit('blockchainOps', stream, function(){
client.blockchain.getBlockStream()
.pipe(es.map(function(block, callback) {
callback(null, util.inspect(block) + '\n')
}))
.pipe(process.stdout)
}());
});
This time I get a socket object returned in the browser console which does not seem to be the stream data I was hoping for.
You're using socket.emit
wrong, you're passing the ACK callback to the client instead of your stream. Have a look at socket.emit
signature :socket.emit(eventName[, ...args][, ack])
.
You probably want something like
socket.emit('blockchainOps', client.blockchain.getBlockStream());
However, I don't think plain socket io supports passing a Stream like that. To pipe a stream down to the client you could use socketio-stream. It would look like this:
var ss = require('socket.io-stream');
var stream = ss.createStream();
ss(socket).emit('blockchainOps', stream);
client.blockchain.getBlockStream().pipe(stream);
EDIT:
On the client, you should be able to read your stream like this:
<script src="socket.io/socket.io.js"></script>
<script src="socket.io-stream.js"></script>
...
ss(socket).on('blockchainOps', function(stream) {
var binaryString = "";
stream.on('data', function(data) {
for(var i=0;i<data.length;i++) {
binaryString+=String.fromCharCode(data[i]);
}
});
stream.on('end', function(data) {
console.log(binaryString);
binaryString = "";
});
});
这篇关于如何通过 socket.io 将数据流式传输到客户端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!