2011-04-24 13 views
6

El servidor nodejs 'pone' esta corriente JSON de Twitter y lo envía al cliente:nodejs - análisis chunked Twitter JSON

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

Los datos devueltos al cliente es 'fragmentada' JSON y ambos JSON.parse (fragmento) y eval ('(' + fragmento + ')') en el lado del cliente dan como resultado errores de análisis. La concatenación de las piezas al plato y esperar a que el evento 'fin' no es una solución, ya sea

me di muestras anteriores utilizan algo como esto en el lado del cliente que al parecer trabajaba antes:

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

estoy el uso de esta en el lado del cliente y el resultado es un error de análisis:

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

sé que su regreso con éxito un trozo JSON con:

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

Servidor:

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

¿Ha cambiado algo o qué otra cosa em haciendo mal?

ACTUALIZACIÓN: El evento 'final' no se activa porque su transmisión?

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() { 

    }); 

... 

Estoy buscando la diferencia con http 1.0 y http 1.1 en cuanto al envío de datos fragmentados.

+2

¿está seguro de concatenar los fragmentos y esperar a que el evento final no funcione? Creo que es la forma en que debería hacerse ya que no puede analizar el medio pedazo recibido. – neebz

Respuesta

15

Mire la sección titulada Parsing Responses en la documentación de Twitter.

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.

En el lado del servidor, se van acumulando trozos hasta que vea el retorno de carro "\r". Una vez que se encuentra el retorno de carro, extraiga la cadena hasta el retorno de carro, y eso nos da un tweet.

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

El cliente se vuelve simple. Simplemente analice el mensaje de socket como JSON en su totalidad.

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

Creo que debería ser message.split ("\ r"). ForEach (función (tweet) – user713886

+0

buena llamada @user. Debería ser "\ r". – Anurag

2

@Anurag I'cant añadir comentarios, sin embargo, en lugar de

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

que debe ser:

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

devolver el carro no es el último carácter.

+0

gracias por señalar esto. He cambiado un poco mi implementación Los fragmentos de Twitter no siempre terminan en una nueva línea o un retorno de carro. – Anurag