nodejs - анализ чанкованного твиттера json - PullRequest
6 голосов
/ 24 апреля 2011

Сервер nodejs «получает» этот поток JSON из Twitter и отправляет его клиенту:

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

Данные, возвращаемые клиенту, представляют собой «фрагментированный» JSON и JSON.parse (chunk) иeval ('(' + chunk + ')') на стороне клиента приводит к ошибкам синтаксического анализа.Объединение фрагментов и ожидание события 'end' также не является решением

Я заметил, что в предыдущих примерах использовалось что-то подобное на стороне клиента, которое, очевидно, работало раньше:

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

Что-то изменилось или что-то еще я делаю неправильно?

ОБНОВЛЕНИЕ: Событие 'end' не запускается из-за потоковой передачи?

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 в том, что касается отправки фрагментированных данных.

Ответы [ 3 ]

15 голосов
/ 25 апреля 2011

Посмотрите на раздел под названием Анализ ответов в документации Twitter.

Анализ ответов JSON от Streaming API прост, каждый объект возвращается в отдельной строке и заканчивается возвратом каретки. Символы новой строки (\ n) могут встречаться в элементах объекта (например, в текстовом элементе объекта статуса), но возврат каретки (\ r) не должен.

На стороне сервера продолжайте накапливать порции, пока не увидите возврат каретки "\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);
});
2 голосов
/ 26 апреля 2011

@ Anurag Я не могу добавлять комментарии, однако вместо

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

должно быть:

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

Возврат каретки не последний символ.

0 голосов
/ 05 июля 2012

Я бы порекомендовал передать ответ в анализатор JSON.Вы можете использовать это: https://github.com/dominictarr/JSONStream

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...