2011-04-24 64 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