【问题标题】:How to stream data over socket.io to client如何通过 socket.io 将数据流式传输到客户端
【发布时间】:2018-07-15 13:59:39
【问题描述】:

我有 socket.io 从服务器向客户端发送一个基本对象。这一点工作正常。

现在想使用event-stream(特别是区块链查询的结果)将流从服务器发送到客户端。我在浏览器控制台中得到了意想不到的结果..

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

    });

我在客户端控制台中得到的似乎是某种 TCP 套接字函数,

ƒ (){if(!n){n=!0;var r=a(arguments);u("sending ack %j",r),e.packet({type:i.ACK,id:t,data:r})}}

谁能帮助我了解发生了什么以及我做错了什么?

== 编辑更新 ==

按照 cmets 中的建议,我已尝试将 socket.io-stream 增强为 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)


}());

});

这次我在浏览器控制台中返回了一个套接字对象,这似乎不是我希望的流数据。

【问题讨论】:

    标签: node.js sockets socket.io event-stream


    【解决方案1】:

    如果有人正在寻找有效的 socket.io 流示例

    // server side
    const { pipeline } = require('stream')
    const server = require('http').Server().listen(8080)
    const io = require('socket.io')(server)
    const ss = require('socket.io-stream')
    
    io.on('connection', (socket) => ss(socket).on('stream', (stream) => {
      pipeline(stream, process.stdout,  (err) => err && console.log(err))
    }));
    
    
    // client side
    const client = require('socket.io-client')
    const socket = client.connect('http://localhost:8080')
    
    socket.on('connect', () => {
      const stream = ss.createStream()
      ss(socket).emit('stream', stream)
      pipeline(process.stdin, stream,  (err) => err && console.log(err))
    });
    
    

    【讨论】:

      【解决方案2】:

      您使用 socket.emit 错误,您将 ACK 回调传递给客户端而不是您的流。看看socket.emitsignature:socket.emit(eventName[, ...args][, ack])

      你可能想要类似的东西

      socket.emit('blockchainOps', client.blockchain.getBlockStream());
      

      但是,我认为普通套接字 io 不支持传递这样的 Stream。要将流向下传输到客户端,您可以使用socketio-stream。它看起来像这样:

      var ss = require('socket.io-stream');
      var stream = ss.createStream();
      
      ss(socket).emit('blockchainOps', stream);
      client.blockchain.getBlockStream().pipe(stream);
      

      编辑:

      在客户端上,您应该能够像这样读取您的流:

          <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-stream 不是与event-stream 重复吗?我一直无法将 getBlockStream() 的结果通过管道传输到套接字中。
      • 它们用于不同的目的,socketio-stream 允许您向下传递流socket.emit,而event-stream 只是节点流的包装器。我已经更新了我的答案,你可以试试吗?请注意,您必须将区块链流pipe 发送到您通过var stream = ss.createStream();创建的流
      • Daniel,我愿意接受你的回答,但是如何从这个 IOStream 对象中提取我的数据呢?我在这里找不到任何看起来像 getBlockStream(); 的结果的东西;
      • 我已经发布了一个如何在浏览器中读取 Stream 的示例,请记住,您需要 socketio-stream 客户端 &lt;script src="socket.io-stream.js"&gt;&lt;/script&gt;。您可以轻松地从 cdn cdnjs.com/libraries/socket.io-stream 获取它
      • 我会试试这个。感谢您抽出宝贵时间查看此内容。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-21
      • 2023-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多