Ho bisogno di un servizio web per questo caso? Sincronizzazione dei dati su più client

3

Sono nuovo in questo settore e un po 'confuso sulle mie attuali riflessioni su un'implementazione del servizio web per la mia applicazione. Voglio sincronizzare tutti i client connessi con i dati attuali su un DB MySQL. Mi sono avvicinato per utilizzare i servizi web come per scopi di coordinamento, ma mi sono bloccato.

Il modo in cui ho provato a implementarlo è ...

Il servizio web sta eseguendo un demone per controllare / ascoltare le operazioni CRUD che interessano i dati DB. Una volta che si è verificata un'operazione CRUD, viene cancellato per notificare a tutti i client connessi e ciascun client a sua volta aggiorna il JTable con i dati del DB corrente e informa l'utente delle modifiche avvenute sul DB.

Questo è dove sono bloccato ...

Il modo in cui penso è (forse?) sbagliato, dal momento che concettualmente i servizi web sono in attesa delle richieste dei clienti e quindi gli inviamo la risposta corrispondente. Ma qui, non ci sono richieste da parte dei clienti. Il servizio web invia semplicemente una risposta (noification), che deve essere multicast poiché non è al corrente di un client "chiamante" - non c'è richiesta.

Pertanto, per mandare una richiesta a un cliente, è necessario "cron" per tutto il tempo del servizio web se si è verificata una modifica sul DB. Quindi il servizio web si presenta come vero o falso con i dettagli CRUD (CRUDEventFired (event_type, event_details)). Ma questo non è ottimale in quanto creerà traffico grande e (molto) inutile soprattutto quando non si verifica alcuna operazione CRUD. Inoltre, ci saranno due diversi deamons (uno nel servizio web e l'altro nell'app client) che controllano / ascoltano lo stesso tipo di evento e questo è ridondante.

Inoltre, con questa implementazione sembra che non sia affatto necessario un servizio Web e che il codice per controllare il DB per le modifiche possa essere implementato nel client. D'altro canto, l'impostazione del client responsabile delle modifiche del DB richiederebbe di codificare le stesse funzioni su piattaforme diverse (desktop, ios, android, ecc.), Mentre l'impostazione del servizio web come coordinatore per la sincronizzazione dei dati tra client richiederebbe il codice solo una volta la funzione appropriata e ciascun client implementano semplicemente il proprio NotificationListener ().

È sbagliato il modo in cui sto pensando di utilizzare i servizi web? Come dovrebbe essere cambiato? Ho anche bisogno di usare i servizi web?

Allego il mio diagramma per la tua convenienza.

    
posta John Astralidis 12.05.2015 - 19:32
fonte

2 risposte

1

Non sono uno specialista, ma qui ci sono i miei due centesimi. Presumo che il tuo webservice funzioni su un server di applicazioni Java EE.

  • tutte le scritture sul DB dovrebbero provenire dal tuo server delle applicazioni, quindi dovresti essere in grado di generare eventi nel tuo codice ogni volta che scrivi nel DB
  • invece del servizio web che è meglio per le query del client, è possibile utilizzare sia websocket che una coda di messaggi (in genere una coda JMS)

Anche se avere i clienti scrivere direttamente nel DB può sembrare allettante all'inizio (è più facile da capire) può diventare rapidamente un casino. Ad esempio, apportare modifiche al DB in futuro potrebbe richiedere l'aggiornamento di tutti i client.

    
risposta data 14.05.2015 - 16:20
fonte
3

Sembra che tu stia cercando di implementare notifiche push dal tuo servizio back-end a ogni client front-end.

Mi vengono in mente due opzioni:

  1. WebSockets consentirà ai tuoi clienti di mantenere un canale di comunicazione bidirezionale persistente con il server. Gli aggiornamenti sul client possono essere inviati lungo il canale persistente e quando il server Web riceve una modifica all'archivio dati, può propagarlo a ciascun client connesso. Usando questo, ogni client probabilmente (più su questo più tardi) avrà i dati più aggiornati ogni volta che vorrà apportare una modifica ad esso

  2. Sondaggio lungo HTTP è un metodo precedente (che funziona abbastanza bene) che utilizza HTTP con timeout lunghi per realizzare qualcosa di simile agli aggiornamenti push. Ogni client apre una richiesta HTTP per alcune risorse e ha un timeout lungo (ad esempio, 2 minuti per esempio). Quando qualcosa cambia, il server risponderà con i nuovi dati, altrimenti attenderà per 2 minuti prima di inviare una risposta 304 NON MODIFICATA al server. In questo modo, il client può ricevere le notifiche abbastanza rapidamente, ma senza un polling costante.

Entrambe queste idee possono essere lette qui: link

Entrambe queste opzioni risentono della possibilità che due client desiderino apportare aggiornamenti contemporaneamente e uno sovrascriva l'altro. In questo modo è facile per il tuo data-store diventare fuori sincrono o avere incoerenze logiche al suo interno. Se vuoi evitare questo, come menzionato pjc50, potresti prendere in considerazione l'utilizzo di un database distribuito.

Per coloro che pensano che sia utile, ecco alcuni pseudo-codice per il polling lungo:

client e sondaggi a lungo termine pseudo-code del server

/**
 * Handles long-poll request for one client and sends updated
 * content to the client when it changes, or a 304 NOT MODIFIED
 * response if it doesn't change within the timeout period
 */

handleClientRequest(HTTRequest clientRequest) {
    String uri = clientRequest.getURI();
    int timeout = clientRequest.getTimeout();

    /* Wait for the resource to change. You should use
     * a more sophisticated waiting scheme, like semaphores,
     * java monitors, or any number of thread synchronization
     * techniques
     */
    while ((resource hasnt changed) && (total wait time < timeout))
        sleep(timeout / 100)

    if (resource did change)
        send new content
    else
        send HTTP 304 NOT MODIFIED response
}

/**
 * Continually sends long-poll requests to the server,
 * and updates data whenever it changes
 */
clientLongPoll(uri) {
    int timeout = 120 // seconds

    while (true) {
        HttpRequest request = new Request(uri);
        request.setTimeout(timeout);

        /* this will hang until the server responds, up to 2 minutes */
        HttpResponse response = request.send()  
        if (resposne.contentChanged() == true)
            update local data store
    }
}

Le librerie di socket Web di solito si basano su uno schema basato su eventi (onConnected (), onNewMessage (), onDisconnected (), ecc ...), ma ciascuna libreria è diversa. L'idea di base è che ogni volta che un client si avvia, dovrebbe contattare il server per avviare una connessione WebSockets e da lì, ognuno può inviare messaggi avanti e indietro ogni volta che cambiano i loro dati locali.

    
risposta data 13.07.2015 - 20:30
fonte

Leggi altre domande sui tag