View Full Version : [vari] Interazione tra utenti in un'applicazione web
ingframin
28-03-2013, 11:34
Buon giorno a tutti,
ho bisogno di una spiegazione sul tema in topic.
Non mi serve codice, e' proprio sulla teoria che sono poco ferrato.
Il problema e' fare interagire due o piu' utenti connessi ad un sito che fa riferimento alla stessa applicazione web.
Supponiamo per semplicita' che si tratti di una chat ma puo' essere qualsiasi interazione.
Ora nella mia mente malata avviene questo:
0) tengo traccia delle sessioni aperte in una tabella del mio database
1) X utenti "entrano" nell'area comune cliccando sull'apposito bottone/link/quello che e'
2) Quando cliccano, un javascript (usando ajax?) in qualche modo comunica alla mia applicazione "ehy io utente xyz sto entrando nella stanza abc".
3) l'applicazione genera una tabella T relativa alla nuova "stanza" che si viene a creare in cui memorizza gli utenti connessi (tramite un id di sessione?) e il contenuto inviato dagli utenti
4) Ogni volta che l'utente invia dei dati (testo della chat o equivalente) c'e' un javascript (usando ajax?) che manda i dati alla mia applicazione.
5) l'applicazione memorizza i dati nella tabella e li rispedisce "broadcast" a tutti gli utenti
6) Il javascript che gira nel browser degli utenti intercetta i dati in arrivo (sempre con ajax?) e li stampa a video senza fare il refresh della pagina.
Quando un utente abbandona la "stanza" il suo id di sessione viene tolto dalla tabella dei presenti o marcato come assente.
Quando l'ultimo utente abbandona la "stanza" rimuovo la tabella dal database.
Ora... questo meccanismo e' frutto della mia mente malata, quindi veniamo alle domande:
1) Funziona davvero cosi'?
2) Esiste un sistema piu' efficiente/veloce? (penso che con quello che ho scritto io il database e' abbastanza "stressato")
3) Esistono delle librerie gia' scritte per qualche linguaggio per fare questo? (lato server intendo)
4) Sapete indicarmi se ci sono libri o siti web o qualsiasi altra cosa su cui posso studiare come si risolvono questi problemi?
Grazie :)
cdimauro
28-03-2013, 12:20
Buon giorno a tutti,
ho bisogno di una spiegazione sul tema in topic.
Non mi serve codice, e' proprio sulla teoria che sono poco ferrato.
Il problema e' fare interagire due o piu' utenti connessi ad un sito che fa riferimento alla stessa applicazione web.
Supponiamo per semplicita' che si tratti di una chat ma puo' essere qualsiasi interazione.
Ora nella mia mente malata avviene questo:
0) tengo traccia delle sessioni aperte in una tabella del mio database
1) X utenti "entrano" nell'area comune cliccando sull'apposito bottone/link/quello che e'
2) Quando cliccano, un javascript (usando ajax?) in qualche modo comunica alla mia applicazione "ehy io utente xyz sto entrando nella stanza abc".
Fin qui ok, e la risposta è sì: usando Javascript (AJAX). In futuro si potrebbero usare i websocket, ma è ancora prematuro.
3) l'applicazione genera una tabella T relativa alla nuova "stanza" che si viene a creare in cui memorizza gli utenti connessi (tramite un id di sessione?) e il contenuto inviato dagli utenti
La tabella è meglio che sia già presente nel server. Ogni stanza avrà un proprio id, e idem per gli utenti.
Se stanze e utenti sono entità "stabili", cioè permanenti nel sistema / db, avranno quindi un loro ben preciso id associato, e quindi lasciamo perdere il concetto di sessione. La sessione serve a identifica e gestire un utente, i cui dati reali (incluso l'id) sono memorizzati nel db e non accessibili dall'esterno.
4) Ogni volta che l'utente invia dei dati (testo della chat o equivalente) c'e' un javascript (usando ajax?) che manda i dati alla mia applicazione.
Sì, AJAX.
5) l'applicazione memorizza i dati nella tabella e li rispedisce "broadcast" a tutti gli utenti
Dopo vediamo il concetto di broadcast, ma ci siamo.
6) Il javascript che gira nel browser degli utenti intercetta i dati in arrivo (sempre con ajax?) e li stampa a video senza fare il refresh della pagina.
Sì, sempre AJAX. Ci sarà un timer che si sveglia ogni tanto (ogni secondo, ad esempio), e che fa polling sul server (sempre tramite AJAX), prelevando l'elenco dei messaggi nuovi rispetto all'ultima interrogazione.
Quando un utente abbandona la "stanza" il suo id di sessione viene tolto dalla tabella dei presenti o marcato come assente.
Quando l'ultimo utente abbandona la "stanza" rimuovo la tabella dal database.
Basta rimuovere gli utenti man mano che vanno via. Quando non ce ne sarà nessuno, la tabella sarà vuota (e quindi, di fatto, sparisce anche la stanza).
Ora... questo meccanismo e' frutto della mia mente malata, quindi veniamo alle domande:
1) Funziona davvero cosi'?
All'incirca sì.
2) Esiste un sistema piu' efficiente/veloce? (penso che con quello che ho scritto io il database e' abbastanza "stressato")
Puoi usare un db NoSQL per gestire i messaggi, e scalare / distribuire il carico di lavoro.
L'ideale, a mio avviso, è tenere un db tradizionale (SQL) per memorizzare le informazioni "stabili" (gli utenti, le stanze, e le loro informazioni, inclusi gli id), che rendono semplice la loro gestione.
Mentre per quelle "aleatorie", come l'elenco dei (nuovi) messaggi, si memorizzano in una piattaforma NoSQL.
Il server pescherà dall'una e/o dall'altra piattaforma a seconda di quello che gli server. Un po' di caching, poi, sarebbe ottimale, in modo da ridurre il carico sul db.
3) Esistono delle librerie gia' scritte per qualche linguaggio per fare questo? (lato server intendo)
In Python ci sono librerie per gestire il protocollo JSON-RPC, molto usato e comodo per questi casi.
Personalmente ho smanettato con apache + mod_wsgi per implementare un server JSON-RPC. Ho realizzato anche un moduletto per gestire in maniera comoda il tutto, in modo da ridurre il codice delle API alla sola "business logic".
Potresti fare qualcosa del genere anche tu. E' molto più semplice di quello che si possa pensare.
4) Sapete indicarmi se ci sono libri o siti web o qualsiasi altra cosa su cui posso studiare come si risolvono questi problemi?
Grazie :)
Francamente non saprei. Se conosci già come metter sù un server web, il passo è breve per realizzare quanto chiedi. Ovviamente roba come caching richiede più lavoro, ma inizialmente a te interessa che il server funzioni; pensare a come ottimizzarlo c'è tempo. ;)
Andrea_RBRW
28-03-2013, 12:48
Se il discorso è x una chat, di solito viene usato Java xkè puoi creare connessioni dirette tra utente e utente... senza quindi passare x il server, x il database o fare (come nel caso di "chat" in pagine web..) continue richieste adl db x sapere se ci sono nuovi messaggi...
ingframin
28-03-2013, 13:17
Fin qui ok, e la risposta è sì: usando Javascript (AJAX). In futuro si potrebbero usare i websocket, ma è ancora prematuro.
La tabella è meglio che sia già presente nel server. Ogni stanza avrà un proprio id, e idem per gli utenti.
Se stanze e utenti sono entità "stabili", cioè permanenti nel sistema / db, avranno quindi un loro ben preciso id associato, e quindi lasciamo perdere il concetto di sessione. La sessione serve a identifica e gestire un utente, i cui dati reali (incluso l'id) sono memorizzati nel db e non accessibili dall'esterno.
Sì, AJAX.
Dopo vediamo il concetto di broadcast, ma ci siamo.
Sì, sempre AJAX. Ci sarà un timer che si sveglia ogni tanto (ogni secondo, ad esempio), e che fa polling sul server (sempre tramite AJAX), prelevando l'elenco dei messaggi nuovi rispetto all'ultima interrogazione.
Basta rimuovere gli utenti man mano che vanno via. Quando non ce ne sarà nessuno, la tabella sarà vuota (e quindi, di fatto, sparisce anche la stanza).
All'incirca sì.
Puoi usare un db NoSQL per gestire i messaggi, e scalare / distribuire il carico di lavoro.
L'ideale, a mio avviso, è tenere un db tradizionale (SQL) per memorizzare le informazioni "stabili" (gli utenti, le stanze, e le loro informazioni, inclusi gli id), che rendono semplice la loro gestione.
Mentre per quelle "aleatorie", come l'elenco dei (nuovi) messaggi, si memorizzano in una piattaforma NoSQL.
Il server pescherà dall'una e/o dall'altra piattaforma a seconda di quello che gli server. Un po' di caching, poi, sarebbe ottimale, in modo da ridurre il carico sul db.
In Python ci sono librerie per gestire il protocollo JSON-RPC, molto usato e comodo per questi casi.
Personalmente ho smanettato con apache + mod_wsgi per implementare un server JSON-RPC. Ho realizzato anche un moduletto per gestire in maniera comoda il tutto, in modo da ridurre il codice delle API alla sola "business logic".
Potresti fare qualcosa del genere anche tu. E' molto più semplice di quello che si possa pensare.
Francamente non saprei. Se conosci già come metter sù un server web, il passo è breve per realizzare quanto chiedi. Ovviamente roba come caching richiede più lavoro, ma inizialmente a te interessa che il server funzioni; pensare a come ottimizzarlo c'è tempo. ;)
Oh che bello, non sono lontano dal concetto.
In realta' la curiosita' mi e' venuta pensando a un browser game e a come fosse possibile implementarlo.
Non mi mettero' di certo a farlo pero' la curiosita' di capire era troppa.
Certo che usare 2 db (uno SQL e uno NoSQL) e' un po' complesso(?)... o forse piu' costoso (noleggio di 2 db diversi) che complesso.
Secondo te sarebbe possibile fare una cosa del genere su un servizio come webfaction?
Intendo senza mettere in piedi il server io stesso.
Oppure serve un VPS?
Non credo lo mettero' mai on line ma mi sa che questo weekend lungo di pasqua provo a farlo sul mio pc :)
Grazie delle info!
ingframin
28-03-2013, 13:21
Se il discorso è x una chat, di solito viene usato Java xkè puoi creare connessioni dirette tra utente e utente... senza quindi passare x il server, x il database o fare (come nel caso di "chat" in pagine web..) continue richieste adl db x sapere se ci sono nuovi messaggi...
Intendi dire con una applet?
In teoria puoi usare qualunque linguaggio per creare connessioni dirette tra utente e utente, ma onestamente e' una cosa che eviterei prima di tutto per motivi di sicurezza! Per creare connessioni dirette bisogna che i due utenti si scambino l'IP... Inoltre gli ip dei provider spesso e volentieri sono dinamici, quindi che succede se i due si scambiano un file e il provider cambia ti cambia l'IP? La connessione muore e va ripristinata, questa cosa va gestita...
Inoltre non credo che abbia molto senso un'applicazione web che fa comunicare due utenti direttamente, a quel punto tanto vale fare un link diretto e bypassare il web evitando tutte le magagne dovute a HTTP e al suo essere stateless
cdimauro
28-03-2013, 14:18
Oh che bello, non sono lontano dal concetto.
In realta' la curiosita' mi e' venuta pensando a un browser game e a come fosse possibile implementarlo.
Non mi mettero' di certo a farlo pero' la curiosita' di capire era troppa.
Capito. Comunque bisogna vedere se e quanto debba scalare il progetto.
Certo che usare 2 db (uno SQL e uno NoSQL) e' un po' complesso(?)... o forse piu' costoso (noleggio di 2 db diversi) che complesso.
Certamente. E' più costoso a livello implementativo e di testing.
Secondo te sarebbe possibile fare una cosa del genere su un servizio come webfaction?
Intendo senza mettere in piedi il server io stesso.
Oppure serve un VPS?
Francamente non ne ho idea di cosa sia webfaction. Un VPS è esagerato. Ti basta un normale servizio di hosting (sperando che se ne trovi uno economico con supporto a Python, nel mio caso).
Non credo lo mettero' mai on line ma mi sa che questo weekend lungo di pasqua provo a farlo sul mio pc :)
Grazie delle info!
Buona fortuna e buone feste. :)
ingframin
28-03-2013, 15:04
Francamente non ne ho idea di cosa sia webfaction. Un VPS è esagerato. Ti basta un normale servizio di hosting (sperando che se ne trovi uno economico con supporto a Python, nel mio caso).
Buona fortuna e buone feste. :)
http://www.webfaction.com/?utm_expid=14099218-11
Te... guarda che bellezza...
Ci carichi su quello che vuoi e costa una fesseria :)
Buona pasqua!
cdimauro
28-03-2013, 19:01
In effetti per quello che offrono, è un prezzo stracciato.
Peccato che non ci sia già installato Firebird. La cosa che mi rompe le scatole è questa (http://docs.webfaction.com/software/home-install.html). Non sono un sistemista e non mi piace questo lavoro: vorrei avere già tutto pronto...
Andrea_RBRW
28-03-2013, 20:07
Intendi dire con una applet?
In teoria puoi usare qualunque linguaggio per creare connessioni dirette tra utente e utente, ma onestamente e' una cosa che eviterei prima di tutto per motivi di sicurezza! Per creare connessioni dirette bisogna che i due utenti si scambino l'IP... Inoltre gli ip dei provider spesso e volentieri sono dinamici, quindi che succede se i due si scambiano un file e il provider cambia ti cambia l'IP? La connessione muore e va ripristinata, questa cosa va gestita...
Inoltre non credo che abbia molto senso un'applicazione web che fa comunicare due utenti direttamente, a quel punto tanto vale fare un link diretto e bypassare il web evitando tutte le magagne dovute a HTTP e al suo essere stateless
Rettifica parziale... se devi fare una chat puoi usare il java... l'ip viene cambiato solo se ci si disconnette.... ma nel caso del java non hai continue interrogazioni al database ke rallentano il sistema inquanto quando scrivi il messaggio viene mandato a tutti quelli connessi e basta...
differente se devi inviare file o x un gioco online... :D
ingframin
30-03-2013, 08:08
Sempre restando in tema, non riesco a capire un'altra cosa.
L'architettura di un "sito" io me la sono sempre immaginata così:
C'è un computer su cui girano un programma server (tipo Apache) e un DBMS (tipo Postgres, MySQL, Oracle,...). Su questo computer io carico la mia applicazione e la faccio partire ma non gira per conto suo, gira all'interno di una specie di sandbox messa in piedi da Apache o da chi per lui. Quando Apache riceve le richieste HTTP dirette verso la mia applicazione glie le gira e poi rimanda indietro la risposta.
Ora però mi rendo conto che questa cosa scricchiola perché ad esempio:
Come funzionano sistemi come Tornado (http://www.tornadoweb.org/en/stable/) o Node.js (http://nodejs.org/)? Sono sistemi indipendenti che non hanno bisogno di un web server o si limitano a gestire in maniera diversa le richieste che ricevono dal webserver?
Perché, ad esempio, su Webfaction si possono caricare Node.js e anche Tornado e credo che si possano anche caricare applicazioni scritte in Go usando l'HTTP sever fornito dal linguaggio.
Al momento l'unica spiegazione che so darmi è che il server è diviso in due fettine: una che spacchetta i pacchetti di rete (fino al livello trasporto di OSI per intenderci) mentre l'altra si limita ai livelli che stanno sopra (applicazione e presentazione) ed è quella che viene attivata quando carico Node.js su un hosting web preesistente.
È corretto oppure ho fatto un gran fritto misto? :confused:
Ritengo di avere poche idee molto ben confuse :doh:
Andrea_RBRW
30-03-2013, 18:42
Sempre restando in tema, non riesco a capire un'altra cosa.
L'architettura di un "sito" io me la sono sempre immaginata così:
C'è un computer su cui girano un programma server (tipo Apache) e un DBMS (tipo Postgres, MySQL, Oracle,...). Su questo computer io carico la mia applicazione e la faccio partire ma non gira per conto suo, gira all'interno di una specie di sandbox messa in piedi da Apache o da chi per lui. Quando Apache riceve le richieste HTTP dirette verso la mia applicazione glie le gira e poi rimanda indietro la risposta.
Ora però mi rendo conto che questa cosa scricchiola perché ad esempio:
Come funzionano sistemi come Tornado (http://www.tornadoweb.org/en/stable/) o Node.js (http://nodejs.org/)? Sono sistemi indipendenti che non hanno bisogno di un web server o si limitano a gestire in maniera diversa le richieste che ricevono dal webserver?
Perché, ad esempio, su Webfaction si possono caricare Node.js e anche Tornado e credo che si possano anche caricare applicazioni scritte in Go usando l'HTTP sever fornito dal linguaggio.
Al momento l'unica spiegazione che so darmi è che il server è diviso in due fettine: una che spacchetta i pacchetti di rete (fino al livello trasporto di OSI per intenderci) mentre l'altra si limita ai livelli che stanno sopra (applicazione e presentazione) ed è quella che viene attivata quando carico Node.js su un hosting web preesistente.
È corretto oppure ho fatto un gran fritto misto? :confused:
Ritengo di avere poche idee molto ben confuse :doh:
è un pò diverso...
tutte le richieste arrivano al webserver... questo le smista... se sono pagine php vanno all'apaches, Pyton (quindi tornado) viene gestito in altro modo,... il webserver di fatto ritorna solamente le pagine statiche, quindi html puro...
se trova degli script all'interno, li fa eseguire dall'ente preposto... ke può essere sullo stesso server, ma anke su server diversi (vedi iterazioni con il database..)
una volta ke ki di dovere ha eseguito il codice, viene data la pagina risultante al webserver ke la spedisce al richiedente...
molto probabilmente ho usato termini sbagliati, ma spero di aver chiarito un pò la cosa... :D
Node.js nn ho capito bene cosa faccia...
Implementare una chat come ti è stato suggerito è semplice ma discretamente inefficiente. In particolare, continuare a interrogare il server ogni secondo (tramite AJAX per esempio) causa una mole molto grande di traffico inutile verso il server quindi non è una buona soluzione se si vuole scalare verso l'alto e gestire molti utenti.
Per risolvere questo problema ci sono varie tecniche:
- fai long polling. In pratica funziona così: il client fa una get verso il server (AJAX va benissimo) ma questo non risponde fin quando non ha dei dati utili per il client. Nel frattempo lascia il socket aperto e ci scrive asincronamente quando il dato è pronto. Non appena il client riceve il dato, aggiorna la UI e fa immediatamente partire una nuova richiesta in un loop continuo (c'è una variante a questo tipo di implementazione, tuttavia il concetto è sempre lo stesso). Con questa soluzione, il server non viene inondato di richieste continue perchè il canale viene chiuso solo quando effettivamente ci sono dati. A grandissime linee, Facebook fa qualcosa di molto simile per implementare notifiche e altri aggiornamenti della parte client;
- utilizzi i web socket che sono stati implementati in Tomcat da circa un anno a questa parte e ti offrono un canale di comunicazione bidirezionale su cui client e server possono scrivere asincronamente. Ottimo per situazioni tipo chat o webgame. Attenzione che vengono usate altre porte (se non ricordo male) quindi eventuali proxy e/o firewall potrebbero incazzarsi.
Direi che la soluzione migliore è quella del long polling, molto facile da implementare se usi Java come linguaggio lato server e relative servlet.
cdimauro
02-04-2013, 12:12
Sempre restando in tema, non riesco a capire un'altra cosa.
L'architettura di un "sito" io me la sono sempre immaginata così:
C'è un computer su cui girano un programma server (tipo Apache) e un DBMS (tipo Postgres, MySQL, Oracle,...). Su questo computer io carico la mia applicazione e la faccio partire ma non gira per conto suo, gira all'interno di una specie di sandbox messa in piedi da Apache o da chi per lui. Quando Apache riceve le richieste HTTP dirette verso la mia applicazione glie le gira e poi rimanda indietro la risposta.
Ora però mi rendo conto che questa cosa scricchiola perché ad esempio:
Come funzionano sistemi come Tornado (http://www.tornadoweb.org/en/stable/) o Node.js (http://nodejs.org/)? Sono sistemi indipendenti che non hanno bisogno di un web server o si limitano a gestire in maniera diversa le richieste che ricevono dal webserver?
Perché, ad esempio, su Webfaction si possono caricare Node.js e anche Tornado e credo che si possano anche caricare applicazioni scritte in Go usando l'HTTP sever fornito dal linguaggio.
Al momento l'unica spiegazione che so darmi è che il server è diviso in due fettine: una che spacchetta i pacchetti di rete (fino al livello trasporto di OSI per intenderci) mentre l'altra si limita ai livelli che stanno sopra (applicazione e presentazione) ed è quella che viene attivata quando carico Node.js su un hosting web preesistente.
È corretto oppure ho fatto un gran fritto misto? :confused:
Ritengo di avere poche idee molto ben confuse :doh:
Parlo per Tornando, perché non so come funziona node.js: è esso stesso un webserver, per cui non ha bisogno di uno come apache per girare.
Apache, come pure Lighttpd, è un webserver che smista le richieste che gli arrivano al codice che si occuperà poi di processarle, il tutto offrendo un po' di funzionalità più avanzate.
Ma il suo lavoro potrebbe benissimo farlo un server "monolitico", che fa tutto da solo.
Ad esempio, prova a eseguire questo da command line:
python -m SimpleHTTPServer
E poi apri con un browser la seguente URL: http://127.0.0.1:8000/ ;)
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.