2011-07-04 23 views
12

Estoy escribiendo un servicio de transmisión simple JSON. Consiste en mensajes JSON, enviados intermitentemente, durante un largo período de tiempo (semanas o meses).Elección de transportes para JSON sobre TCP

¿Cuál es la mejor práctica con respecto al envío de múltiples mensajes JSON a través de un socket TCP simple?

Algunas alternativas que he mirado (y sus desventajas) son:

  1. nueva línea separada JSON - desventaja: los saltos de línea dentro de JSON requieren escapar, o prohibición
  2. WebSocket inspirado encuadre 0x00 0xFF - desventaja: es ahora binario, no UTF-8 más
  3. websockets reales - inconveniente: la falta de (opensource) WebSocket cliente bibliotecas
  4. http multiparte http://www.w3.org/Protocols/rfc1341/7_2_Multipart.html - inconveniente: el cliente incompletos ¿apoyo?
  5. sin delimitadores - desventaja: CHUNKING requiere análisis JSON (no se puede contar sólo curlies debido a curlies en cuerdas)

¿Hay una manera buena, o al menos bien establecida de hacer esto?

+0

¿qué ocurre al abrir/cerrar el zócalo entre cada mensaje? – fvu

+0

@fvu en horas punta, podemos tener diez o más mensajes por segundo, por lo que esto no es eficiente. También podría causar agotamiento de NAT en enrutadores débiles. – fadedbee

+0

¿Por qué no se pueden contar los curlies? uno podría detectar y evitar el conteo de los cráneos en cuerdas, ¿no podría? – moala

Respuesta

1

He codificado lo que yo y algunos otros desarrolladores están haciendo:

http://en.wikipedia.org/wiki/Line_Delimited_JSON

Tiene la ventaja de ser compatible netcat/telnet.

Consulte también: http://ndjson.org/

+3

como dije en wikipedia no es el mejor lugar para crear trabajos originales que debas poner en otro lado –

+1

esto ciertamente no se parece a ningún "estándar", ni algo que aconsejaría a nadie. las implementaciones propuestas son extremadamente ineficaces (analizando todo hasta el momento en cada salto de línea: O (n^2)) o depende de "analizadores personalizados". Recién notado, esa página wikipedia está escrita por chrisdew, y la "implementación de referencia" es suya. Eso infringe 4 de los 7 criterios de contenido – Javier

+0

@Javier No entiendo cómo se puede desarrollar el análisis sintáctico O (n^2). Por lo que entiendo basta con line = readline() luego analizar (línea) que son O (n) operaciones –

12

mis primeras dos opciones serían:

  1. Haz lo que los protocolos TCP temprana no: enviar un mensaje (un objeto JSON en su caso) y cerrar la conexión. El cliente lo detecta y vuelve a abrir para obtener el siguiente objeto.

    • pros: muy fácil de analizar, no hay bytes adicionales (contenido) enviados. cualquier pérdida de datos significa perder solo un objeto. si puedes soportar eso, no es necesario agregar la retransmisión a tu aplicación.
    • contras: si envía un (enorme) lote de (muy) pequeños objetos, el handshake de tres paquetes TCP se suma a la latencia.
  2. hacer lo HTTP fragmentada-mode: en primer lugar enviar el número de bytes en el objeto JSON, un salto de línea (CRLF en HTTP), y su objeto JSON. El cliente solo tiene que contar los bytes para saber cuándo el siguiente byte sería el próximo objectsize.

    • profesionales: mantiene una transmisión duradera.
    • contras: unos pocos bytes adicionales, debe mantener un flujo de larga duración, por lo que las interrupciones y reconexiones accidentales deben manejarse como eventos excepcionales; es necesario establecer algunos apretones de manos para continuar donde falló.
+0

Puede considerar lo que oberstet sugirió. Para mis proyectos, normalmente utilizo Netstrings o Bencing-like framing. Fácil de implementar en la mayoría de los casos y solo agrega una sobrecarga mínima. – BastiBen

5

Cuando se quiere servir a los clientes de explorador, el más cercano se llega a TCP prima es WebSockets.

WebSockets tiene suficiente impulso como para que los proveedores de navegadores mejoren el soporte (Chrome 14 y Firefox 7/8 admiten el último borrador de protocolo) y que una amplia gama de marcos de cliente y servidor lo admitirán.

Hay son ya un par de bibliotecas de cliente de código abierto, incluyendo Autobahn WebSocket.

Cuando usted quiere hornear algo por su cuenta (por encima de TCP crudo), yo recomendaría un formato de longitud prefijada para sus mensajes JSON, es decir Netstrings

responsabilidad: Soy autor de autopista y de trabajo para Tavendo.

+0

+1 para Netstrings/Bencoding – BastiBen

0

Puede utilizar Server-Sent Events.

var source = new EventSource('/EventSource'); 

source.onmessage = function(e) { 
    var data = JSON.parse(e.data); 
    console.log(e.data); 
}; 

source.onopen = function(e) { 
    console.log('EventSource opened'); 
}; 

source.onerror = function(e) { 
    console.log('EventSource error'); 
};