Pregunta

¿Hay alguna forma de " suscribirse " ¿De los objetos GWT a JSON se transmiten y escuchan los eventos entrantes en una conexión keep-alive, sin intentar recuperarlos todos a la vez? Creo que la palabra de moda para esta tecnología es " Comet " ;.

Supongamos que tengo un servicio HTTP que abre la conexión keep-alive y pongo los objetos JSON con cotizaciones de acciones entrantes allí en tiempo real:

{" símbolo " ;: " AAPL " ;, " bid " ;: " 88.84 " ;, " ask ": " 88.86 "}
{" símbolo " ;: " AAPL " ;, " oferta " ;: " 88.85 " ;, " preguntar ": " 88.87 "}
{" símbolo " ;: " IBM " ;, " oferta " ;: " 87.48 " ;, " pregunta ": " 87.49 "}
{" símbolo " ;: &u- gt; " ;, " oferta " ;: " 305.64 " ;, " pregunta ": " 305.67 "}
...

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

¿Fue útil?

Solución

Hay un módulo GWT Comet para StreamHub:

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

StreamHub es un servidor Comet con una edición comunitaria gratuita. Hay un ejemplo de ello en acción aquí .

Necesitará descargar el servidor StreamHub Comet y crear un nuevo SubscriptionListener, usar el ejemplo StockDemo como punto de partida, luego 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);
...

Descargue el archivo JAR del sitio de códigos de Google, agréguelo a la ruta de clase de sus proyectos GWT y agregue la inclusión a su módulo GWT:

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

Conéctate y suscríbete desde tu 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, procese las actualizaciones como desee en el escucha de actualizaciones (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 olvide incluir streamhub-min.js en la página HTML principal de sus proyectos GWT.

Otros consejos

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 los datos. Dependiendo de lo que esté haciendo exactamente, es posible que no sea necesario complicar las cosas en exceso.

Primero que nada, en el lado del cliente, no creo que GWT pueda soportar adecuadamente cualquier tipo de datos de transmisión. La conexión debe cerrarse antes de que el cliente pueda procesar los datos. Lo que esto significa desde un punto de vista de empuje del servidor es que su cliente se conectará al servidor y lo bloqueará hasta que los datos estén disponibles, momento en el que regresarán. Cualquier código que se ejecute en la conexión completada debe volver a abrir inmediatamente una nueva conexión con el servidor para esperar más datos.

Desde el punto de vista del servidor, simplemente entra en un ciclo de espera (el paquete concurrente de Java es particularmente ú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 dependiendo de cómo es el flujo de datos, pero aquí hay algunas en las que pensar:

  • ¿Es importante que un cliente obtenga 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 vuelve a conectarse.
  • ¿Habrá montones de actualizaciones? Si este es el caso, podría ser más inteligente empaquetar una cantidad de actualizaciones y empujar los trozos a la vez cada varios segundos en lugar de que el cliente obtenga 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 empuje 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 se 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.

de hecho, existe una biblioteca similar a cometd para gwt - http://code.google.com / p / gwteventservice /

Pero personalmente no lo he usado, así que realmente no puedo responder si es bueno o no, pero el doco parece bastante bueno. vale la pena intentarlo.

Hay algunos otros que he visto, como cometd de gwt-rocket biblioteca.

Se pueden encontrar algunas ideas preliminares para la implementación de Comet para GWT aquí ... aunque me pregunto si hay algo más maduro.

También, hay información sobre la integración de GWT / Comet disponible allí , incluso con Más tecnología de vanguardia: " Continuaciones de embarcadero " ;. Vale la pena echarle un vistazo.

Aquí puede encontrar una descripción (con algunas ejemplos de origen) de cómo hacer esto para IBM WebSphere Application Server. No debería ser demasiado diferente con Jetty o cualquier otro servidor J2EE habilitado para cometas. Brevemente, la idea es: codificar su objeto Java en una 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 utilizando GWT RPC. Voila! :)

Mi experiencia con esta configuración es positiva, no hubo problemas con ella, excepto por las preguntas de seguridad. No está realmente claro cómo implementar la seguridad para el 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.

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

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. En el lado del servidor, utiliza un Servlet simple.

Actualmente lo estamos utilizando en producción con más de 1000 usuarios concurrentes en un entorno agrupado. Tuvimos algunos problemas en el camino que debían resolverse modificando la fuente de Atmosphere. También la documentación es muy fina.

El marco es de uso gratuito.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top