2011-04-24 48 views
6

的服务器的NodeJS从Twitter“获取”这个JSON数据流,并将其发送给客户端:的NodeJS - 解析分块Twitter的JSON

stream.twitter.com/1/statuses/filter.json?track=gadget 

的数据返回给客户端的“分块” JSON和两个JSON.parse (chunk)和eval('('+ chunk +')')导致解析错误。 串接夹持件,等待“结束”事件不是解决的办法

我注意到前面的例子中使用这样的事情上显然奏效之前客户端:我

socket.onmessage = function(chunk) { 
    data = eval("(" + chunk.data + ")"); 
    alert(data.user.screen_name); 

在客户端使用这一点,它会导致一个解析错误:

var socket = new io.Socket(); 
    socket.on('message', function(chunk) { 
    var data = eval('(' + chunk + ')'); // parsing error 
    alert(data.screen_name): 

我知道,它成功地返回一个JSON块有:

var socket = new io.Socket(); 
     socket.on('message', function(chunk) { 
     alert(chunk): // shows a JSON chunk 

服务器:

response.on('data', function (chunk) { 
    client.each(function(e) { 
     e.send(chunk); 
    }); 

做了一些改变,否则什么时间我做错了吗?

更新:'结束'事件不会触发,因为它的流?

http.get({ 
    headers: { 'content-type': 'application/json' }, 
    host: 'stream.twitter.com', 
    path: '/1/statuses/filter.json?track... 
}, function(res) { 

    res.setEncoding('utf8'); 
    res.on('data', function (chunk) { 
    client.each(function(e) { 
     e.send(chunk); 
    }); 
}); 

    // does not fire 
    res.on('end', function() { 

    }); 

... 

我正在寻找与http 1.0和http 1.1的区别,只要发送分块的数据。

+2

你确定连接块和等待结束事件不起作用吗?我认为这是它应该完成的方式,因为它无法解析接收到的半块。 – neebz 2011-04-24 18:02:19

回答

15

请参阅Twitter文档中标题为Parsing Responses的部分。

Parsing JSON responses from the Streaming API is simple every object is returned on its own line, and ends with a carriage return. Newline characters (\n) may occur in object elements (the text element of a status object, for example), but carriage returns (\r) should not.

在服务器端,不断累积块,直到看到回车符"\r"。一旦找到回车符,将字符串提取到回车符,然后给我们一条推文。

var message = ""; // variable that collects chunks 
var tweetSeparator = "\r"; 

res.on('data', function(chunk) { 
    message += chunk; 

    var tweetSeparatorIndex = message.indexOf(tweetSeparator); 
    var didFindTweet = tweetSeparatorIndex != -1; 

    if (didFindTweet) { 
     var tweet = message.slice(0, tweetSeparatorIndex); 
     clients.forEach(function(client) { 
      client.send(tweet); 
     }); 
     message = message.slice(tweetSeparatorIndex + 1); 
    } 
}); 

客户端变得简单。简单地将套接字消息解析为JSON。

socket.on('message', function(data) { 
    var tweet = JSON.parse(data); 
}); 
+0

我认为它应该是message.split(“\ r”)。forEach(function(tweet) – user713886 2011-04-25 15:16:00

+0

good call @user。它应该是“\ r”。 – Anurag 2011-04-25 16:32:45

2

@Anurag I'cant添加注释,但是代替

if (chunk.substr("-1") == "\r") 

它应该是:

if (chunk.charCodeAt(chunk.length-2) == 13) 

回车不是最后一个字符。

+0

感谢您指出了这一点。 Twitter的大块并不总是以换行符或回车结束。 – Anurag 2011-04-27 06:19:59