Newsgroup: it.comp.lang.delphi
Titolo: Verifica utente già connesso

Ciao a tutti,
avrei bisogno di due dritte anche senza entrare nel dettaglio
su quale tecnica adottare per verificare se un utente ï¿œ giï¿œ connesso.
Spiego brevemente a grandi linee come dovrebbe funzionare il tutto:
Applicativo Delphi 2010 componenti indy
Una parte server in attesa di connessioni tcp, il client si collega 
invia nome utente e password, il server verifica e se ï¿œ autorizzato 
invia dati sino a quando il client ï¿œ connesso.
E fin qui non ho nessun problema.
Quello che vorrei fare ï¿œ tenere traccia degli utenti connessi ed 
impedire che un altro utente con le stesse credenziali si colleghi al 
server se un altro utente ï¿œ giï¿œ connesso con lo stesso user.
Il problema nasce dal fatto che l'utente autenticato e connesso
a causa di brevi interruzioni potrebbe ricollegarsi in automatico piï¿œ 
volte sino a quando non decide di terminare la sessione.
C'ï¿œ qualche tecnica da adottare in casi come questi, avete qualche link
per documentarmi ?
Grazie a tutti.


Il server a livello socket esegue il "listen" e accetta le nuove 
connessioni, controlla le credenziali e se esistono gia' disconnette il 
client.
Naturalmente devi tenere una "stringlist" delle credenziali.
Dov'e' il problema? Giorgio

 Dov'e' il problema? Giorgio
 
Il server quando accetta le connessione crea un thread separato, ma in 
caso di una breve disconnessione, il client si riconnette in automatico
e genera un nuovo thread, quindi tenere traccia delle autorizzazioni 
basandomi sull'evento connessione/disconnessione in questo caso non va 
bene, sarei costretto a chiedere a volte ripetutamente user e password 
all'utente.
Senza contare che in quel mentre potrebbe subentrare  il secondo client
con le stesse credenziali e quindi inibire l'accesso al primo.
Avevo pensato ad un sistema di token.
Il client si collega fornendo user e password, il server lo autorizza e 
fornisce un token sotto forma di stringa o numero al client.
Con questo token, il client richiede l'informazione al server
con cadenza di un secondo.
Ad ogni richiesta il server verifica se il token ricevuto è presente in 
una sua lista interna e in caso affermativo invia i dati al richiedente.
Quando il client vuol terminare la sessione invia un comando specifico 
al server allegando il token e questo lo rimuove dalla lista.
In questo modo le sporadiche disconnessioni con relative riconnessioni 
automatiche non dovrebbero influenzare il funzionamento.
Il problema nasce però se il client per qualche motivo viene chiuso
senza che possa mandare il comando di rimozione del token, in questo 
caso la sessione rimane bloccata.
Esiste qualche sistema più veloce ed elegante ?

Manca qlc elemento...
 
1) la comunicazione è monodirenzionale (server -> client) oppure bidirezionale?
Cioe', l'utente chiede e riceve oppure si connette e il server invia dati?
 
2) con indy di default la connessione è sincrona. Tu la forzi ad asincrona?
 
A


Il client si connette al server ed invia le credenziali,
se autenticato parte dal lato client un timer che ad intervalli di un 
secondo inviano al server una richiesta dati, il server risponde a 
questa richiesta inviando i  dati.
In caso di perdita della disconnessione il client in automatico si 
riconnette.
Tutto questo sino a quando il client non viene chiuso.

Cosi su 2 piedi io userei un sistema basato su lease.
 
1) il server ha una lista di elementi (CLASSI!) del tipo:
 
TConnectionInfo = class
public
  property ClientName: string...
  property Ip: string,
  property ConnectedDateTime: TDateTime;
  property SessionKey: string;
  property LastrequestDateTime: TDateTime;
  property LastRequestIndex: integer;
  property ExpirationDateTime: TDateTime;
  property UserName: string;
end;
 
 
2) il client avvia la app
Il lastrequestindex sul client è zero.
Il sessionkey è ad esempio, FormatDateTime(date+time, yyyymmddhhnnsszzz). 
Non usare now che taglia i millisecondi...
Si connette e invia le credenziali e il sessionkey.
 
3) IL server cerca nella lista al punto 1 un elemento avente stesso username.
 
Se lo trova, e il client è diverso e l'elemento NON E' SCADUTO 
(ovvero datetime > expiredatetime), esce: 
l'utente è gia' connesso da un altro client.
 
Se lo trova, e il client lo stesso aggiorna l'elemento.
Se non lo trova, lo inserisce
In entrambi i casi scrive solo nome client, ip, connecteddatetime, username, sessionkey e ExpirationDate. 
Questo valore lo calcoli tu, del tipo DateTime + n minuti/secondi o altro.
 
4) il client deve inviare una richiesta di dati
incrementa il suo lastrequestindex e invia una richiesta al server che include lastrequestindex e sessionkey.
 
5) il server riceve i dati:
cerca nella lista un elemento in base al sessionkey. 
se non lo trova, ESCE E NON MANDA NIENTE.
Stesso client ma sessione diversa, quindi lato client la app è stata chiusa.
 
Altrimenti, aggiorna l'elemento con lastrequestindex (ricevuto dal client), lastrequestdatetime=date+time e EXPIRATIONDATE = expirationdate+ un valore parametrizzabile del tipo 1 minuto/secondo...Infine, invia i dati al client.
 
lato server hai un thread che ogni n unita di tempo si smazza la lista al punto 1 e fa pulizia, ovvero rimuove dalla lista gli elementi che hanno expireddatetime < datetime
 
lato client, se perde la connessione e parte qlcs per il suo ripristino, invia anche sessionkey. Infine alla chiusra della app, viene invata una richiesta al server che forza l'eliminazione del relativo elemento dalla lista.
 
 
Prendi con le pinze....


 
Buona idea,
non avevo pensato a calcolare l'orario di creazione della sessione.
Faccio due prove...
Grazie mille !!!

 TConnectionInfo = class
 
Qui andrebbe benissimo anche un semplice array di record...
 
 
 
 
 
 
 
 
 
 
ok ok scherzavo! :-P
 
ciao
Giacomo
 
 
 
 

 ok ok scherzavo! :-P
 
Mavaf... Rotfl! :-D
 
A.