Come pianificare un'architettura di rete per app client / server per far fronte a più scambi di dati non correlati?

2

Sto codificando una coppia di applicazioni client / server in Java, mentre imparo a riguardo. Ho le funzionalità di base di inviare un messaggio al server e analizzarlo ma nel pensare al quadro generale della loro comunicazione, sono perplesso su dove andare da qui.

Sia il client che il server devono essere in grado di avviare uno scambio di dati, quindi ho bisogno di avere una lettura del thread su ciascun lato, in ogni momento. Inoltre, quando si avvia uno scambio, è necessario ascoltare la risposta. Se lo faccio, però, avrei due thread che leggono i dati, che suppongo non finiscano bene dato che, da quanto ho capito, non sarei in grado di assicurarmi che i dati vengano letti nel thread che voglio.

Vedo alcune opzioni, ma non sono sicuro di andare troppo lontano con ciascuna soluzione poiché la mia conoscenza non mi lascia pensare troppo avanti.

  1. Utilizzare solo il primo thread che in origine era in attesa di dati prima dello scambio, per leggere anche la risposta per la query appena inviata da un thread diverso e inoltrare i dati a cui appartiene.

    Sembra difficile. Se leggo i dati nello stesso thread che lo richiedeva, sarebbe molto semplice rispetto a questo.

  2. Inizia a leggere InputStream nello stesso thread che ha richiesto i dati e crea il thread che era originariamente in ascolto, attendi.

    Il mio problema con questo è che, se ci sono altri dati che arrivano dallo stesso client che non è correlato con la query appena creata, verrebbero recuperati da questo thread invece dell'altro, il che blocca lo scopo della lettura i dati qui.

  3. Stabilire un'altra connessione dal client, a un'altra porta, dopo che il primo è stato stabilito. Quindi potrei usare una presa per gli scambi avviati dall'altra parte, e l'altra per ascoltare le risposte delle query fatte nel frattempo.

    In questo modo saprei esattamente cosa sta succedendo, ma non avrei più questo stesso problema se avessi due query in attesa di dati contemporaneamente?

Sembra una funzionalità semplice, banale da trovare in molte applicazioni, quindi immagino ci sia un metodo provato e vero là fuori e non c'è motivo per me di provare a reinventare la ruota qui.

Quindi, per riassumere, qual è il modo consigliato di configurare applicazioni client / server in grado di gestire finestre di dialogo eventualmente sovrapposte, avviate da una delle due, in momenti imprevedibili?

Ho iniziato a modificare alcune parti della domanda per renderla un po 'più chiara, ma alla fine ho quasi riscritto completamente. Se è ancora un po 'di confusione è perché sono confuso. Penso che mi manchi un punto semplice ma non sono stato in grado di trovare esempi che mostrino questo.

    
posta Smig 19.12.2012 - 20:06
fonte

2 risposte

1

L'utilizzo di più connessioni per utente potrebbe essere problematico perché il limite di connessione dei server verrà raggiunto in precedenza quando si hanno molti utenti.

TCP, tuttavia, ha il vantaggio che i pacchetti vengono sempre ricevuti in modo completo e in ordine. Puoi utilizzarlo per implementare il tuo sistema di gestione delle sessioni a livello di applicazione che funziona in modo premiscelato ("multiproprietà") multi-threading.

Quando si verificano più download di file contemporaneamente, è possibile suddividere ciascun trasferimento di file in singoli pacchetti e prefisso ogni pacchetto con un identificatore che indica a quale trasferimento di file appartiene. Quindi si mettono i pacchetti di ogni trasferimento in una coda e si elaborano queste code in ordine round-robin. Ciò significa che quando si hanno 3 trasferimenti di file A, B e C composti da 3, 5 e 7 pacchetti ciascuno, si invieranno questi 15 pacchetti nell'ordine ABCABCABCBCBCCC. Assicurati di essere in grado di aggiungere una nuova coda in qualsiasi momento tra le mandate, in modo da poter inserire un nuovo trasferimento mentre altri trasferimenti sono in esecuzione.

Dall'altro lato si legge il prefisso di ciascun pacchetto per scoprire a quale trasferimento di file appartiene e aggiungerlo al flusso di input corrispondente.

Una buona API per gestire tutto questo su Java è non -blocking IO . Dovresti comunque utilizzarlo su un server che gestisce molti utenti, perché in questo modo eviti di creare singoli thread per tutti gli utenti.

    
risposta data 22.12.2012 - 12:52
fonte
0

Un modo comune per farlo sarebbe avere il client mantenere una connessione TCP persistente al server (ad esempio, una volta che il client si connette al server, rimane connesso fino alla chiusura del client).

Poiché le connessioni TCP sono bidirezionali, il client e il server sono entrambi liberi di inviare dati attraverso il socket TCP in qualsiasi momento.

(Si noti che la parte più difficile di questa configurazione è la ricezione di dati: invece di fare un modello sincrono dove il client invia qualcosa, quindi blocca l'attesa di ritorno dei dati di ritorno, il client deve essere pronto a ricevere i dati dal server in qualsiasi momento ... ma deve anche essere in grado di gestire contemporaneamente altre attività, come gli eventi della GUI. Ciò può essere fatto dedicando un thread alla ricezione di dati e / o utilizzando un I / O asincrono modello)

    
risposta data 20.12.2012 - 01:14
fonte

Leggi altre domande sui tag