Domanda

Esiste un modo per " iscriversi " da GWT a flusso di oggetti JSON e ascoltare gli eventi in arrivo su una connessione keep-alive, senza cercare di recuperarli tutti in una volta? Credo che la parola d'ordine per questa tecnologia sia "Comet".

Supponiamo che io abbia un servizio HTTP che apre una connessione keep-alive e inserisce oggetti JSON con quotazioni di borsa in arrivo lì in tempo reale:

{" 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 "}
...

Devo ascoltare questi eventi e aggiornare i componenti GWT (tabelle, etichette) in tempo reale. Qualche idea su come farlo?

È stato utile?

Soluzione

Esiste un modulo cometa GWT per StreamHub:

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

StreamHub è un server Comet con un'edizione comunitaria gratuita. Ne esiste un esempio in azione qui .

Dovrai scaricare il server StreamHub Comet e creare un nuovo SubscriptionListener, utilizzare l'esempio StockDemo come punto di partenza, quindi creare un nuovo JsonPayload per lo streaming dei dati:

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

Scarica il JAR dal sito del codice di Google, aggiungilo al tuo percorso di classe dei progetti GWT e aggiungi l'inclusione al tuo modulo GWT:

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

Connetti e iscriviti dal tuo codice 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);
...

Quindi elabora gli aggiornamenti come preferisci nel listener di aggiornamenti (anche nel codice 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;
          ...
      }
}

Non dimenticare di includere streamhub-min.js nella pagina HTML principale dei tuoi progetti GWT.

Altri suggerimenti

Ho usato questa tecnica in un paio di progetti, anche se ha dei problemi. Devo notare che l'ho fatto solo in modo specifico tramite GWT-RPC, ma il principio è lo stesso per qualunque meccanismo si stia utilizzando per gestire i dati. A seconda di cosa stai facendo esattamente, potrebbe non esserci molto bisogno di complicare troppo le cose.

Prima di tutto, sul lato client, non credo che GWT possa supportare correttamente qualsiasi tipo di dati di streaming. La connessione deve essere chiusa prima che il client possa effettivamente elaborare i dati. Ciò significa da un punto di vista push del server che il client si connetterà al server e si bloccherà fino a quando i dati non saranno disponibili, a quel punto torneranno. Qualunque codice venga eseguito sulla connessione completata, è necessario riaprire immediatamente una nuova connessione con il server per attendere ulteriori dati.

Dal lato server, si passa semplicemente ad un ciclo di attesa (il pacchetto simultaneo java è particolarmente utile per questo con blocchi e timeout), fino a quando non saranno disponibili nuovi dati. A quel punto, il server può restituire un pacchetto di dati al client che si aggiornerà di conseguenza. Ci sono un sacco di considerazioni a seconda di come è il tuo flusso di dati, ma qui ci sono alcuni a cui pensare:

  • È importante che un client riceva ogni singolo aggiornamento? In tal caso, il server deve memorizzare nella cache eventuali eventi potenziali tra il momento in cui il client riceve alcuni dati e quindi si riconnette.
  • Ci saranno degli aggiornamenti? In questo caso, potrebbe essere più saggio impacchettare un certo numero di aggiornamenti e spingere in giù blocchi alla volta ogni diversi secondi piuttosto che fare in modo che il client ottenga un aggiornamento alla volta.
  • Probabilmente il server avrà bisogno di un modo per rilevare se un client è andato via per evitare di accumulare enormi quantità di pacchetti memorizzati nella cache per quel client.

Ho scoperto che c'erano due problemi con l'approccio push del server. Con molti client, ciò significa molte connessioni aperte sul server web. A seconda del server Web in questione, ciò potrebbe significare che molti thread vengono creati e tenuti aperti. Il secondo ha a che fare con il limite tipico del browser di 2 richieste per dominio. Se sei in grado di fornire immagini, CSS e altri contenuti statici per domini di secondo livello, questo problema può essere mitigato.

esiste davvero una libreria simile a una cometa per gwt - http://code.google.com / p / gwteventservice /

Ma non l'ho usato personalmente, quindi non posso davvero garantire che sia buono o no, ma il documento sembra abbastanza buono. vale la pena provare.

Ce ne sono alcuni altri che ho visto, come la cometa di gwt-rocket biblioteca.

Alcune idee preliminari per l'implementazione di Comet per GWT sono disponibili qui ... anche se mi chiedo se c'è qualcosa di più maturo.

Inoltre, sono disponibili alcune informazioni sull'integrazione di GWT / Comet , usando anche più tecnologia all'avanguardia: "Jetty Continuations". Vale la pena dare un'occhiata.

Qui puoi trovare una descrizione (con alcuni esempi di origine) su come eseguire questa operazione per IBM WebSphere Application Server. Non dovrebbe essere troppo diverso con Jetty o qualsiasi altro server J2EE abilitato per Comet. In breve, l'idea è: codificare l'oggetto Java in una stringa JSON tramite GWT RPC, quindi utilizzando cometd inviarlo al client, dove viene ricevuto da Dojo, che attiva il codice JSNI, che chiama i metodi del widget, in cui si deserializza l'oggetto usando nuovamente GWT RPC. Ecco! :)

La mia esperienza con questa configurazione è positiva, non ci sono stati problemi ad eccezione delle domande di sicurezza. In questo caso non è davvero chiaro come implementare la sicurezza per la cometa ... Sembra che i servlet di aggiornamento delle comete debbano avere URL diversi e quindi possa essere applicata la sicurezza J2EE.

Il progetto JBoss Errai ha un bus di messaggi che fornisce messaggi bidirezionali che forniscono una buona alternativa a cometd.

Stiamo usando Atmosphere Framewrok ( http://async-io.org/ ) per ServerPush / Comet nell'applicazione GWT.

Sul lato client Framework ha l'integrazione GWT che è piuttosto semplice. Sul lato server utilizza un semplice servlet.

Attualmente lo stiamo utilizzando in produzione con oltre 1000 utenti concorrenti in ambiente cluster. Abbiamo avuto alcuni problemi sulla strada che dovevano essere risolti modificando la fonte dell'atmosfera. Anche la documentazione è molto sottile.

Framework è gratuito da usare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top