Implementazione della chat nel 2013 [chiuso]

1

Ho giocato un po 'con WebSockets e ho iniziato a implementare una piccola chat. L'ultima volta che ho fatto qualcosa del genere era quando non esistevano cose come thread e computer avevano un core singolo. Ho iniziato a pensare a come implementarlo con gli schemi di programmazione di oggi, ma non sono arrivato a nessuna conclusione finale.

Come implementa le funzionalità principali della chat nelle tecniche odierne a livello superiore?

Ora ho il contesto Server, Socket e User. L'utente ha stati Non definito, Connesso, InChat, Disconnesso, Disconnesso, Il mio problema principale è la manutenzione dell'utente:

  • Se l'utente non ha detto "ciao" in 5 secondi dopo l'apertura della connessione - > disconnessione
  • L'utente non risponde a "ping" con "pong" o almeno 2 minuti - > disconnessione
  • L'utente è stato collegato per più di 12 ore - > disconnessione
  • All'utente non è stato assegnato il profilo (nickname e / o altri dettagli) dopo 5 minuti di connessione - > disconnessione
  • Viene attivato un altro flag specifico del programma che esegue il kickout dell'utente - > disconnetti

La mia attuale implementazione è simile a come è stata fatta in passato. vale a dire. Ho

while(serverRunning) 
{ 
  foreach(socket in allSockets)
  {
    user = allUsers.findUserBySocket(socket); 
    doMaintenance(user);
  }
}

Ora questo funziona troppe volte e blocca e blocca tutti gli utenti e tutti i socket troppo.

Come è implementato oggi? Ad esempio, ad esempio?

  • Il socket si collega
  • Aggiungi a allSockets
  • Aggiungi a tutti gli utenti
  • Avvia thread per utente che viene eseguito ogni x secondi ed esegue user.doMaintenance () ?
  • Oppure c'è una coda per utente che viene iniettata con azioni come doPongCheckAction , doProfileTimeoutCheckAction , ecc. ogni x secondi (richiede anche thread per utente che svuota costantemente la coda dell'utente) ?
  • Oppure c'è il thread di manutenzione che viene eseguito ogni x secondi dopo l'ultima esecuzione e scorre attraverso tutti gli utenti (un po 'come l'implementazione corrente)?
  • Oppure c'è un thread che inietta le azioni a tutte le code degli utenti quando c'è troppo tempo quando è stato eseguito lo stesso tipo di azione e altro thread che itera su tutti gli utenti e svuota la coda dell'utente?
  • O qualcos'altro o che non è nemmeno basato sulle code? :)
posta raspi 13.02.2013 - 21:13
fonte

3 risposte

2

Controlla i modelli architettonici come PubSub o Enterprise Service Bus . Le chat room possono essere facilmente modellate su queste linee. Un cliente si connetterebbe al broker e si registrerebbe, sottoscrivendo gli aggiornamenti pubblicati. Inoltre, considera l'utilizzo di un protocollo stabilito per gestire queste connessioni, iscrizioni e registrazioni, ad esempio PubSubHubbub o XMPP sono abbastanza consolidati da aver pensato a problemi e edge-case che non hai ancora, ma abbastanza aperti da permetterti di scrivere il tuo server, usandoli solo come mezzo.

Per rimanere scalabile, eviterei qualsiasi architettura che dipende dal numero di connessioni. La rotazione di un thread per ogni utente non viene ridimensionata una volta che il conteggio degli utenti aumenta e i thread iniziano a diventare reciprocamente.

    
risposta data 13.02.2013 - 21:44
fonte
0

Lo farei con uno o più timer per utente che attivano un evento. Ad esempio, è possibile impostare una funzione pingMissed(user) da chiamare ogni due minuti, che disconnette l'utente. Ogni volta che ricevi una risposta ping da quell'utente, ripristini il timer per altri due minuti. I timer sono supportati dal sistema operativo e utilizzano pochissime risorse durante l'attesa.

    
risposta data 13.02.2013 - 21:40
fonte
0

Un modo per strutturare il tuo loop principale, molto simile a quello che hai, è usare un'architettura event driven :

while(serverRunning) 
{ 
  wait(for something interesting on any of your sockets)
  {
    user = allUsers.findUserBySocket(socket); 
    doMaintenance(user);
  }
}

L'operazione wait() potrebbe essere qualcosa come select , epoll , kqueue , o qualche altra funzione fornita dal kernel a seconda del tuo OS di destinazione. Essenzialmente si fornisce al kernel l'elenco completo dei socket a cui si è interessati, quindi (in modo efficiente) attende che qualcosa di interessante avvenga su uno di questi socket. Quando l'operazione di attesa ritorna, controlla per vedere quale socket ha avuto l'evento interessante (dati ricevuti, socket chiuso, ecc.) E agisci di conseguenza.

Per gestire eventi periodici, puoi tenere un elenco nel tuo codice dei prossimi eventi da licenziare. Quando chiami select o qualsiasi altra cosa, puoi calcolare a che ora dovrebbe essere attivato l'evento successivo e passare un valore di timeout corrispondente alla funzione di attesa.

    
risposta data 17.02.2013 - 21:48
fonte

Leggi altre domande sui tag