我正在使用通过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 JS,nodejs 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>
任何帮助或指导都会令人惊讶,因为它真的很挣扎。
答案 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}}