解析TCP JSON Stream并通过Socket.io发出每个对象

时间:2016-08-19 16:00:12

标签: json node.js sockets tcp socket.io

我正在使用通过TCP套接字发送JSON流的数据源,我正在使用node.js / socket.io将流发送到浏览器客户端。

一切正常,但我需要将每个JSON对象作为来自socket.io服务器的单独消息发出。在客户端中,收到的消息如下:

//Message 1:
{"type":"TYPE_1","odds":[{"eventId":"foo","odds":[{"oddId":foo,"oddType":"LIVE","source":"foo"}]}]}
//Message 2:
{"type":"TYPE_2","odds":[{"eventId":"foo","odds":[{"oddId":foo,"oddType":"LIVE","source":"foo"}]}]}
{"type":"TYPE_3","odds":[{"eventId":"foo","odds":[{"oddId":foo,"oddType":"LIVE","source":"foo"}]}]}
//Message 3:
{"type":"TYPE_4","odds":[{"eventId":"foo","od
//Message 4:
ds":[{"oddId":foo,"oddType":"LIVE","source":"foo"}]}]}

数据Feed文档声明:“发送到您的应用程序的所有消息都将形成JSON流(消息之间没有分隔符),因此您可能需要一个支持JSON流的解码器。”

因此,流是严格正确的,但我需要将每个对象作为单独的消息。

我查看了https://www.npmjs.com/package/JSONStream和其他人,但我对nodejs和socketio很新,并且不确定如何将它们实现到服务器中。

还阅读了How can I parse the first JSON object on a stream in JSnodejs JSON.parse(data_from_TCP_socket)http://www.sebastianseilund.com/json-socket-sending-json-over-tcp-in-node.js-using-sockets

我认为这与缓冲区块长度有关,而且它们太大,所以消息会分裂,但这可能是错误的!我猜我需要一个分隔符支票来平衡括号,但不确定如何去做或者是否采用正确的方法。

我的服务器脚本:

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var net = require('net');
var port = 8992;              // Datafeed port
var host = '127.0.0.1';      // Datafeed IP address

//Whenever someone connects this gets executed
io.on('connection', function(socket){
  console.log('A user connected to me the server');

  //Whenever someone disconnects this piece of code executed
  socket.on('disconnect', function () {
    console.log('A user disconnected');
  });
});

//Create a TCP socket to read data from datafeed
var socket = net.createConnection(port, host);

socket.on('error', function(error) {
  console.log("Error Connecting");
});

socket.on('connect', function(connect) {
  console.log('connection established');
  socket.write('{"type":"SUBSCRIBE"}');
});

socket.on('data', function(data) {
  //console.log('DATA ' + socket.remoteAddress + ': ' + data);
  var data = data.toString();
  io.sockets.emit('event', JSON.stringify(data));
});

http.listen(3000, function(){
  console.log('listening on *:3000');
});

我的客户:

<!DOCTYPE html>
<html>
  <head><title>Hello world</title></head>
  <script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
  <script src="http://code.jquery.com/jquery-1.11.1.js"></script>
  <script>
    var socket = io.connect('http://localhost:3000');
  </script>
  <body>
    <form action="">
      <input id="m" autocomplete="off" /><button>Send</button>
    </form>
    <ul id="messages"></ul>
    <script>
      socket.on('event', function(data){
        var t = JSON.parse(data.toString('utf8'));
        $('#messages').prepend($('<li>').text(t));
        console.log('Got event from Server:', t);
      });
    </script>
  </body>
</html>

任何帮助或指导都会令人惊讶,因为它真的很挣扎。

1 个答案:

答案 0 :(得分:1)

要使用的常用分隔符是换行符(var sockBuf = ''; socket.setEncoding('utf8'); socket.on('data', function(data) { sockBuf += data; var i; var l = 0; while ((i = sockBuf.indexOf('\n', l)) !== -1) { io.sockets.emit('event', sockBuf.slice(l, i)); l = i + 1; } if (l) sockBuf = sockBuf.slice(l); }); )。如果您已将其附加到JSON消息中,则可以非常轻松地解析消息。例如:

var sockBuf = '';
socket.setEncoding('utf8');
socket.on('data', function(data) {
  var i = data.indexOf('\n');
  if (i === -1) {
    sockBuf += data;
    return;
  }
  io.sockets.emit('event', sockBuf + data.slice(0, i));
  var l = i + 1;
  while ((i = data.indexOf('\n', l)) !== -1) {
    io.sockets.emit('event', data.slice(l, i));
    l = i + 1;
  }
  sockBuf = data.slice(l);
});

或更有效但稍微不那么简单的解决方案:

{{1}}