2009-03-06 17 views
6

¿Hay alguna manera de "suscribirse" de objetos GWT a objetos JSON y escuchar los eventos entrantes en la conexión keep-alive, sin tratar de buscarlos todos a la vez? Creo que la palabra de moda para esta tecnología es "Cometa".GWT/Comet: alguna experiencia?

Supongamos que tengo servicio HTTP que se abre de mantener activa la conexión y poner JSON objetos con las cotizaciones de bolsa entrantes allí en tiempo real:

{"symbol": "AAPL", "bid": "88.84", "ask":"88.86"}
{"symbol": "AAPL", "bid": "88.85", "ask":"88.87"}
{"symbol": "IBM", "bid": "87.48", "ask":"87.49"}
{"symbol": "GOOG", "bid": "305.64", "ask":"305.67"}
...

Necesito escuchar estos eventos y actualizar los componentes de GWT (tablas, etiquetas) en tiempo real. ¿Alguna idea de como hacerlo?

Respuesta

6

hay un módulo Comet GWT para StreamHub:

http://code.google.com/p/gwt-comet-streamhub/

StreamHub es un servidor cometa con una edición gratuita comunidad. Hay un ejemplo de esto en acción here.

Usted tendrá que descargar el servidor StreamHub Comet y crear un nuevo SubscriptionListener, utilice el ejemplo StockDemo como punto de partida, a continuación, crear un nuevo JsonPayload para transmitir los datos:

Payload payload = new JsonPayload("AAPL"); 
payload.addField("bid", "88.84"); 
payload.addField("ask", "88.86"); 
server.publish("AAPL", payload); 
... 

Descargar el JAR el sitio de google Code, agregarlo a su GWT proyectos ruta de clase y agregue el include a su módulo de GWT:

<inherits name="com.google.gwt.json.JSON" /> 
<inherits name="com.streamhub.StreamHubGWTAdapter" /> 

Connect y suscribirse a partir del código GWT:

StreamHubGWTAdapter streamhub = new StreamHubGWTAdapter(); 
streamhub.connect("http://localhost:7979/"); 
StreamHubGWTUpdateListener listener = new StockListener(); 
streamhub.subscribe("AAPL", listener); 
streamhub.subscribe("IBM", listener); 
streamhub.subscribe("GOOG", listener); 
... 

luego procesar las actualizaciones cómo te gusta en el oyente actualización (también en el código GWT):

public class StockListener implements StreamHubGWTUpdateListener { 
     public void onUpdate(String topic, JSONObject update) { 
      String bid = ((JSONString)update.get("bid")).stringValue(); 
      String ask = ((JSONString)update.get("ask")).stringValue(); 
      String symbol = topic; 
      ... 
     } 
} 

no se olvide de incluir streamhub-min.js en sus proyectos GWT página HTML principal.

+0

Hola. ¿Hay alguna manera de deshabilitar el navegador de hacer el molesto símbolo de "carga" en el cursor, es decir, cargarlo en Chrome, aparece un círculo blanco molesto. Como se puede imaginar, tener una aplicación que necesita estar abierta durante mucho tiempo y tener ese símbolo de carga constantemente ¡se vuelve bastante molesto! Gracias. – Federer

1

Algunas ideas preliminares para la implementación de Comet para GWT se pueden encontrar en here... aunque me pregunto si hay algo más maduro.

1

También se puede obtener información sobre la integración de GWT/Comet en there, utilizando aún más tecnología de punta: "Jetty Continuations". Vale la pena echarle un vistazo.

3

En efecto, existe una biblioteca cometd similar para GWT - http://code.google.com/p/gwteventservice/

Pero no ve personalmente lo utilizaron, por lo que realmente no puedo responder por si su buena o no, pero el mana parece bastante bueno. vale la pena intentarlo.

Hay algunos otros que he visto, como la biblioteca gwt-rocket's cometd.

5

He usado esta técnica en un par de proyectos, aunque tiene sus problemas. Debo señalar que solo he hecho esto específicamente a través de GWT-RPC, pero el principio es el mismo para cualquier mecanismo que esté utilizando para manejar datos. Dependiendo de lo que esté haciendo exactamente, es posible que no haya mucha necesidad de complicar demasiado las cosas.

En primer lugar, en el lado del cliente, no creo que GWT pueda admitir correctamente ningún tipo de transmisión de datos. La conexión debe cerrarse antes de que el cliente pueda procesar los datos. Lo que esto significa desde el punto de vista del servidor push es que su cliente se conectará al servidor y lo bloqueará hasta que los datos estén disponibles y en qué punto regresará. Cualquiera que sea el código que se ejecute en la conexión completada, debe reabrir inmediatamente una nueva conexión con el servidor para esperar más datos.

Desde el lado del servidor, simplemente ingrese en un ciclo de espera (el paquete concurrente de Java es especialmente útil para esto con bloques y tiempos de espera), hasta que haya nuevos datos disponibles. En ese momento, el servidor puede devolver un paquete de datos al cliente, que se actualizará en consecuencia. Hay un montón de consideraciones según cómo sea el flujo de datos, pero estos son algunos puntos a tener en cuenta:

  • ¿Es importante para un cliente recibir todas las actualizaciones? Si es así, entonces el servidor necesita almacenar en caché cualquier evento potencial entre el momento en que el cliente obtiene algunos datos y luego se vuelve a conectar.
  • ¿Va a haber un montón de actualizaciones? Si este es el caso, podría ser más prudente empaquetar una cantidad de actualizaciones y empujar hacia abajo cada segundo en vez de hacer que el cliente reciba una actualización a la vez.
  • Es probable que el servidor necesite una forma de detectar si un cliente se ha ido para evitar acumular grandes cantidades de paquetes en caché para ese cliente.

Encontré que había dos problemas con el enfoque de inserción del servidor. Con muchos clientes, esto significa muchas conexiones abiertas en el servidor web. Dependiendo del servidor web en cuestión, esto podría significar que muchos subprocesos se creen y mantengan abiertos. El segundo tiene que ver con el límite del navegador típico de 2 solicitudes por dominio. Si puede servir sus imágenes, CSS y otro contenido estático para dominios de segundo nivel, este problema puede ser mitigado.

+0

+1 Excelente publicación con grandes ideas. – Federer

+0

+1 Así es exactamente como lo hago. La solución al problema de "muchos hilos" se deletrea "solicitudes suspendibles" en la especificación de Servlet 3.0. Jetty tiene soporte temprano para esto en 7.0. Tomcat lo llama algo más. –

0

Here puede encontrar una descripción (con algunos ejemplos de fuentes) de cómo hacer esto para IBM WebSphere Application Server. No debería ser muy diferente con Jetty o cualquier otro servidor J2EE habilitado para Comet. Brevemente, la idea es: codificar su objeto Java en cadena JSON a través de GWT RPC, luego usar cometd enviarlo al cliente, donde Dojo lo recibe, lo que activa su código JSNI, que llama a sus métodos de widgets, donde deserializa el objeto de nuevo usando GWT RPC. Voila! :)

Mi experiencia con esta configuración es positiva, no hubo ningún problema excepto las preguntas de seguridad. No está claro cómo implementar la seguridad del cometa en este caso ... Parece que los servlets de actualización de Comet deberían tener diferentes URL y luego se puede aplicar la seguridad J2EE.

0

El proyecto JBoss Errai tiene un bus de mensajes que proporciona mensajes bidireccionales que proporcionan una buena alternativa a cometd.

0

Estamos utilizando Atmosphere Framewrok (http://async-io.org/) para ServerPush/Comet en la aplicación GWT.

En el lado del cliente, Framework tiene una integración GWT que es bastante sencilla. Del lado del servidor, utiliza Servlet simple.

Actualmente lo estamos utilizando en producción con más de 1000 usuarios concurent en entornos agrupados. Tuvimos algunos problemas en el camino que tuvieron que resolverse modificando la fuente de Atmosphere. Además, la documentación es muy delgada.

Framework es de uso libre.

Cuestiones relacionadas