2

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

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

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

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

== 编辑更新 ==

正如评论中所建议的,我已经尝试使用 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)


}());

});

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

在此处输入图像描述

4

2 回答 2

4

如果有人正在寻找一个有效的 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))
});

于 2020-05-23T15:20:55.060 回答
3

您使用socket.emit错误,您将 ACK 回调传递给客户端而不是您的流。看看socket.emit 签名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 = "";
       });
    });
于 2018-02-05T17:06:21.977 回答