Ik heb een simpel chat programma wat ik aan het maken ben alleen nu moet hij kunnen zien of iemand online/offline is. Nu doet hij dat ook wel door als hij een error krijgt van de client dat hij denkt dat de persoon waarmee hij wou connecten offline is. Alleen nu duurt dat wel verschrikuluk lang(15 sec).... Als de client gewoon kan connecten dan denkt hij dat de ander online is. Maaruh is er iemand die weet hoe het beter kan (met het testen van offline status?)
Dat een eigenschap van tcp/ip. Je zou kunnen pingen met een kortere tijd. Of misschien de timeout van sockets lager zetten, maar dat heeft ook weer nadelen natuurlijk.
We adore chaos because we like to restore order - M.C. Escher
Hoe kan ik de timout van de sockets veranderen dan? En wat voor nadelen kan dat precies geven? Dat mensen met een trage verbinding problemen krijgen?
Verwijderd
volgens mij is wat jij zoekt non-blocking sockets. Standaard zijn ze nl blocking, en dat betekent dat je app pas weer de focus krijgt als de call afgelopen is. Bij Non-blocking gaat de focus direct weer terug en hoef je niet op een timeout te wachten.
Als het je echt om de tijd gaat die het duurt voor je weet of iemand offline is, dan kun je natuurlijk gewoon een ping sturen. De timeout kun je zelf verzinnen, natuurlijk. Ik denk dat een seconde of 2 voor een normale verbinding heel redelijk is, maar denk er wel aan dat die 15 seconden ingesteld zijn om ervoor te zorgen dat alles ook nog correct functioneert bij een wat tragere verbinding.
Die time-out is trouwens ook wel op operating system nivo in te stellen (en misschien ook wel in je applicatie, maar daar weet ik niets van), maar om dat nu ten behoeve van die ene applicatie aan te gaan passen, lijkt me wat te ver gaan.
In alle gevallen moet je zelf nog even uitzoeken hoe het in Delphi moet, helaas. Misschien dat je met Google iets kan vinden, gebruikmakend van een term als ICMP ping.
Die time-out is trouwens ook wel op operating system nivo in te stellen (en misschien ook wel in je applicatie, maar daar weet ik niets van), maar om dat nu ten behoeve van die ene applicatie aan te gaan passen, lijkt me wat te ver gaan.
In alle gevallen moet je zelf nog even uitzoeken hoe het in Delphi moet, helaas. Misschien dat je met Google iets kan vinden, gebruikmakend van een term als ICMP ping.
Is er iemand die dan misschien weet hoe ik de timout van de client/server-socket kan aanpassen?? Alleen binnen dit progie.
Welke Delphi en welke componenten gebruik je?
Als ik me niet vergis zit er bij de indy componenten automatisch een componentje waarmee je kunt pingen. Heel erg simpel om te gebruiken. Vanaf delphi versie 6 zitten ze er standaard bij en anders moet je ff googlen op indy components ofzo want ze zijn ook los te downloaden.
Edit:
Heb het even voor je opgezocht. Het component heet "IdIcmpClient" en heeft de volgende properties:
- Host (dus het ip wat je wil pingen)
- Port (als ik me niet vergis was dat voor ping 7)
- ReceiveTimeout (is dus de timeout van je ping, ik denk dat 2 seconden inderdaad wel voldoende is)
Denk dat je het hier wel mee red
Edit:
Heb het even voor je opgezocht. Het component heet "IdIcmpClient" en heeft de volgende properties:
- Host (dus het ip wat je wil pingen)
- Port (als ik me niet vergis was dat voor ping 7)
- ReceiveTimeout (is dus de timeout van je ping, ik denk dat 2 seconden inderdaad wel voldoende is)
Denk dat je het hier wel mee red
[ Voor 47% gewijzigd door ProgrammerX op 17-01-2003 18:38 ]
Ohh, dat wist ik nietVerwijderd schreef op 17 January 2003 @ 18:39:
Let er wel op dat TIdIcmpClient op windows nt/2k/xp beheerdersrechten nodig heeft
Verwijderd
omdat TIdIcmpClient raw sockets gebruikt, en raw sockets hebben beheerders rechten nodig. MS heeft een dll die dat probleem opzeild (icmp.dll)
Ik gebruik delphi 5 professional. En dat indy components is dat freeware? Kijk ik wil het liefst gebruik maken van de standaard mogelijkheden in delphi.DaCoTa schreef op 17 January 2003 @ 18:17:
Welke Delphi en welke componenten gebruik je?
Oh, ja en ik gebruik TServerSocket en TClientsocket. Ik laat de clientsocket steeds een poging ondernemen om verbinding te vinden met de serversocket en als die er niet is(een error) dan ziet hij hem offline....DaCoTa schreef op 17 January 2003 @ 18:17:
Welke Delphi en welke componenten gebruik je?
Indy Componenten zijn inderdaad gratis. Sterker nog, vanaf Delphi 6 zitten ze standaard bij Delphi meegeleverd.
Gebruik je Indy? Indy 8 en hoger heeft een optionele TimeOut parameter bij een ReadLn en helaas niet bij de Connect. Indy 9 heeft dat ook.
/edit
TClientSocket heeft het nergens. Je dient daar non-blocking te gebruiken en zelf een thread of timer te starten die een timeout geeft.
/edit
TClientSocket heeft het nergens. Je dient daar non-blocking te gebruiken en zelf een thread of timer te starten die een timeout geeft.
[ Voor 35% gewijzigd door LordLarry op 17-01-2003 19:35 ]
We adore chaos because we like to restore order - M.C. Escher
Dit werkt goed om te kijken of een bepaald ip adres actief is en aangesloten op het internet/netwerk. Alleen wil ik het graag zo hebben dat ik ook direct zeker weet dat op dat ip adres mijn programma actief is. Weet iemand hoe ik dat evt. dan het beste kan testen?ProgrammerX schreef op 17 januari 2003 @ 18:28:
Als ik me niet vergis zit er bij de indy componenten automatisch een componentje waarmee je kunt pingen. Heel erg simpel om te gebruiken. Vanaf delphi versie 6 zitten ze er standaard bij en anders moet je ff googlen op indy components ofzo want ze zijn ook los te downloaden.
Edit:
Heb het even voor je opgezocht. Het component heet "IdIcmpClient" en heeft de volgende properties:
- Host (dus het ip wat je wil pingen)
- Port (als ik me niet vergis was dat voor ping 7)
- ReceiveTimeout (is dus de timeout van je ping, ik denk dat 2 seconden inderdaad wel voldoende is)
Denk dat je het hier wel mee red
Verwijderd
je moet een connectie naar die poort maken (zoals je al deed) of een centrale server gebruiken.ygma!l schreef op 17 januari 2003 @ 20:44:
[...]
Weet iemand hoe ik dat evt. dan het beste kan testen?
Verwijderd
Via UDP broadcast message sturen (UDP zit ook in Indy), daarop client (jouw proggie) laten replyen met een bericht van 'MijnProgv1.0' hierzoygma!l schreef op 17 januari 2003 @ 20:44:
[...]
Dit werkt goed om te kijken of een bepaald ip adres actief is en aangesloten op het internet/netwerk. Alleen wil ik het graag zo hebben dat ik ook direct zeker weet dat op dat ip adres mijn programma actief is. Weet iemand hoe ik dat evt. dan het beste kan testen?
Sorry had niet de hele thread gelezen
Je kan het beste die Indy ff downloaden vanaf de site (het is freeware, in ieder geval voor niet commerciele software zover ik weet). De socket componenten bij Delphi 5, vind ik zelf nogal buggy en onbetrouwbaar. (ik krijg/kreeg niet altijd ondisconnect events etc. binnen). Heb ooit op basis hiervan een aanwezigheids/chat/message programma gebouwd. Had toen nog nooit van Indy (proggie zou nu eigenlijk gerewrite moeten worden met de Indy componenten) gehoord. Heb toen ook iets ingebouwd voor dat pingen etc., ik zal het maandag is ff nakijken voor je.
De Indy9 componenten zijn sterk verbeterd, ze zijn eventueel te downloaden op
http://www.nevrona.com/indy
[ Voor 47% gewijzigd door Verwijderd op 17-01-2003 23:06 ]
Als het zo toch gaat kun je net zo goed de client ook de mededeling laten sturen dat hij offline gaat.Verwijderd schreef op 17 januari 2003 @ 22:45:
[...]
Via UDP broadcast message sturen (UDP zit ook in Indy), daarop client (jouw proggie) laten replyen met een bericht van 'MijnProgv1.0' hierzo
alleen zal dit niet werken met de gewone kills. dus dat er niets meer kan worden verstuurd.
Server laat je getimed UDP broadcasts doen, zodat de clients kunnen bepalen waar de server is. Je kan natuurlijk als je altijd het zelfde IP adres hebt, deze gewoon in de client vast zetten. (niet handig, natuurlijk)
Zodra een client netjes afsluit of plotseling wegvalt, krijg je aan de server kant een onDisconnect event.
Hier in kun je kijken naar TServerSocket.activeConnections (integer) kijken en mbv TServerSocket.connection[i] alle clients aflopen in een loopje. Dit levert een Socket object op waarmee je het ip adres van de client kan op vragen (RemoteAdress)
Zodra een client netjes afsluit of plotseling wegvalt, krijg je aan de server kant een onDisconnect event.
Hier in kun je kijken naar TServerSocket.activeConnections (integer) kijken en mbv TServerSocket.connection[i] alle clients aflopen in een loopje. Dit levert een Socket object op waarmee je het ip adres van de client kan op vragen (RemoteAdress)
[ Voor 5% gewijzigd door Tim Schuhmacher op 17-01-2003 22:59 ]
Ik heb het nu gepbreerd met TIdEcho en TIdECHOServer (van Indy components) alleen is het nu zo dat ik in een lus(while..do) alle ip adressen van andere gebruikers in het programma te testen of ze online/offline zijn(via try...except), alleen door de timout van 2000ms "vertraagt" het progie met 2 sec. Dus als ik bijv. het venster versleep, dan verschijnt hij pas op de nieuwe positie naar 2 sec. Is iemand die weet hoe ik dit kan oplossen?
Verwijderd
Timertje plaatsen, en in de OnTimer event het volgende zetten:
Application.ProcessMessages;
Application.ProcessMessages;
Application.ProcessMessages; ertussen of de gehele controle in een aparte thread stoppen.
brrr application.processmessages gebruiken is zeer vies. Er is ook van indy een component om dat soort dingen op te lossen IdAntiFreeze volgens mij. Probeer eerst die te gebruiken
Ik heb een timertje er bij gezet alleen helpt het niet. Sterker nog: het wordt ergur, want nu is de taakbalk niet eens te gebruiken.... Er is dan nog maar 1 oplossing en CTR+ALT+DEL en taak beeindigen....Verwijderd schreef op 19 January 2003 @ 15:06:
Timertje plaatsen, en in de OnTimer event het volgende zetten:
Application.ProcessMessages;
Verwijderd
Je kan inderdaad ff beter eerst proberen met idAntiFreeze (had ik ff niet aan gedacht),
of Application.ProcessMessages in die lus plaatsen.
Kan je die code van die lus 's ff hier posten?
of Application.ProcessMessages in die lus plaatsen.
Kan je die code van die lus 's ff hier posten?
DIT WERKT!!Just_a_Gamer schreef op 19 januari 2003 @ 15:11:
brrr application.processmessages gebruiken is zeer vies. Er is ook van indy een component om dat soort dingen op te lossen IdAntiFreeze volgens mij. Probeer eerst die te gebruiken
Code: (OnlineClient =TIdEcho)Verwijderd schreef op 19 januari 2003 @ 15:15:
Je kan inderdaad ff beter eerst proberen met idAntiFreeze (had ik ff niet aan gedacht),
of Application.ProcessMessages in die lus plaatsen.
Kan je die code van die lus 's ff hier posten?
onlineclient.Host:=checkip;
try
onlineclient.Connect(2000);
ifonline;//Procedure waarin staat wat hij moet doen als gebruiker online is.
except
ifoffline;;//Procedure waarin staat wat hij moet doen als gebruiker offline is.
end;
onlineclient.Disconnect;
Dat is afhankelijk van hoeveel ip adressen je wil checken.Verwijderd schreef op 19 januari 2003 @ 15:30:
en hoevaak doe je dit?
Verwijderd
Dat snap ik, maar check je dit 1x per 5 minuten of wat??ygma!l schreef op 19 januari 2003 @ 15:38:
[...]
Dat is afhankelijk van hoeveel ip adressen je wil checken.
Nou, ja ik laat het de lus 10 keer per seconden starten, maar de doordat gebruikers offline zijn krijg je een vertraging, Je kunt dus eigenlijk stellen dat hij continu controleert...Verwijderd schreef op 19 January 2003 @ 15:41:
[...]
Dat snap ik, maar check je dit 1x per 5 minuten of wat??
Verwijderd
Ok.
Je gebruikt nu toch die Indy Componenten, waarom maak je geen gebruik van OnDisconnect event van idTcpServer ??
Je gebruikt nu toch die Indy Componenten, waarom maak je geen gebruik van OnDisconnect event van idTcpServer ??
Ik gebruik nu idd Indy Componenten. Ik maak geen gebruik van OnDisconnect, omdat dat alleen werkt als je 2 pesonen hebt.Verwijderd schreef op 19 januari 2003 @ 15:48:
Ok.
Je gebruikt nu toch die Indy Componenten, waarom maak je geen gebruik van OnDisconnect event van idTcpServer ??
Wat is er vies aan "application.processmessages" ??Just_a_Gamer schreef op 19 January 2003 @ 15:11:
brrr application.processmessages gebruiken is zeer vies. Er is ook van indy een component om dat soort dingen op te lossen IdAntiFreeze volgens mij. Probeer eerst die te gebruiken
Verwijderd
omdat je dat meestal alleen nodig hebt als je iets fout gedaan hebt.
De code die dan uitgevoerd wordt kan je dan beter in een thread zetten
De code die dan uitgevoerd wordt kan je dan beter in een thread zetten
Hoe kom je hierbij? IdTcpServer behandeld elke connectie apart, dus als er een OnDisconnect-event plaatsvind, geeft hij door welke socket het betreft, en bij die socket kan je het bijbehorende ip-adres opvragen.ygma!l schreef op 19 January 2003 @ 16:19:
Ik gebruik nu idd Indy Componenten. Ik maak geen gebruik van OnDisconnect, omdat dat alleen werkt als je 2 pesonen hebt.
Dit is al eerder in het draadje ook vermeld.
Ik snap iets niet, wie connect er nou met wie ?
Als de client connect met de server, weet de server toch wie er online is ( Alle connected clients namelijk ) ?
Als de server connect met de client, ... is de server de client toch ?
Of connecten de clients direct met elkaar ? In dat geval zou je misschien eerst een UDP bericht kunnen sturen en die laten echoen oid om aan te geven dat de partner online is.
Als de client connect met de server, weet de server toch wie er online is ( Alle connected clients namelijk ) ?
Als de server connect met de client, ... is de server de client toch ?
Of connecten de clients direct met elkaar ? In dat geval zou je misschien eerst een UDP bericht kunnen sturen en die laten echoen oid om aan te geven dat de partner online is.
Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.
Pagina: 1