There is currently no way implemented to identify the client during the handshake. This is defenetly something I will consider adding to the library.
But, I should point out that identifying clients based on their IPs is bad style, as due to the use of NAT networks, multiple devices usually share an external IP. While in Europe and the US it is usually something like one per household, for some (cheaper) internet providers or providers in other countries that haven't been so lucky with getting large shares of the IP address space, multiple homes or even larger parts like city blocks can share the same IP address. So there could be potentially hundreds of people with the same IP.
Therefore you should give the client a unique ID to reconnect. Like when a game starts, you could generate a game ID, which every client gets. If a client looses it's connection it can reconnect by sending this game ID to the server and the server can recognize this and put it back into the right game
you could generate a game ID, which every client getshow could I use a client ID to make the server contact the specific client by his ID, not IP?
"The (threaded) base handler"socket.AcceptingMethod:=samThreaded?
"when a client disconnects, it changes the indices of all clients connected"Is there any event going on in this situation? how can I know that someone disconnected to update my list?
Warfley, thanks for the explanation, it seems pretty clear, however I'd have several questions:Nope, that makes the accepting handshake threaded (basically before establishing a connection a HTTP request is made, with samThreaded or samThreadPool this will be threaded).
1.Quote"The (threaded) base handler"socket.AcceptingMethod:=samThreaded?
2. Does a new client always get the highest number in ConnectionList? If there are 5 connected clients, I suppose they are numbered 0..4 so the new one will get 5, right?Yes it is a simple TFPGList used. When a client connects it is added to the list via .Add at the end of the list and if it disconnects it is removed via .Delete.
Clients have their user names so basing on ConnectionList, I could have some list linking ConnectionList's client number to the user name but...
3.The list is automatically updated. To be notified on a disconnect you can register an event handler. In the ChatServer example this is done in:Quote"when a client disconnects, it changes the indices of all clients connected"Is there any event going on in this situation? how can I know that someone disconnected to update my list?
TSocketHandler = class(TThreadedWebsocketHandler)ok, got it.
The list is automatically updated. To be notified on a disconnect you can register an event handler. In the ChatServer example this is done in:of course... :| I don't know what I was thinking of when asking this question. I even use that event to do some stuff. What I really wanted to know is how can I figure out which client disconnected, is there any way get its number in ConnectionsList?
of course... :| I don't know what I was thinking of when asking this question. I even use that event to do some stuff. What I really wanted to know is how can I figure out which client disconnected, is there any way get its number in ConnectionsList?Currently there is no nice way of getting it, you basically need to iterate that list and search for it
And there is another question about OnConnectionClosed. I testing the server using my gui and the HTML example. The server notices when the HTML client disconnects, whether I use the disconnect button, refresh the page or even kill the browser process, the server always triggers the OnConnectionClosed event but it doesn't happen with my GUI, whether I close it or just kill the process, the server doesn't notice it. How could I notify the server I disconnect?Thats because you don't perform the closing handshake of websockets, but rather break the TCP connection (which will result in an exception).
To close the connection gracefully just call "TWebsocketCommunicator.Close" and wait until TWebsocketCommunicator.Open is falseworked perfectly!
Currently there is no nice way of getting it, you basically need to iterate that list and search for itI see... anyway I managed to somehow solve it. I dug through your code to find out how you implemented ConnectionList and what info it exactly stores.
$ ./chatServer
Server is starting
Connected to 192.168.1.1 <- Client A connects
Message from 192.168.1.1: ClientA <- and everything is ok, it's able to send the Hello message
Hello message received
(MessageReceived) LOCK... ...locked
CL[0].UserID:='ClientA'
(MessageReceived) UNLOCK... ...unlocked
Connected to 192.168.1.3 <-The same with Client B, everything is ok. It connects from another PC
Message from 192.168.1.3: ClientB
Hello message received
(MessageReceived) LOCK... ...locked
CL[1].UserID:='ClientB'
(MessageReceived) UNLOCK... ...unlocked
<-here I fired Client C but it didn't reach the server. I ran it on the same PC that ClientA
cl <-I typed 'cl' on the server to see what's in ConnectionList
(DoHandleCommunication) LOCK... ...locked
Count=2
0 ClientA
1 ClientB <-and there is no info about Client C
(DoHandleCommunication) UNLOCK... ...unlocked
$ ./TestChat ClientC
1 MyUserID=ClientC
chat.FCommunicator.Open=true
Hello message sent
$ ./chatServer
Server is starting
Connected to 192.168.1.3 <-Client1 connects and sends the Hello message but Server doesn't receive it
Connected to 192.168.1.3 <-Client2 connects
Message from 192.168.1.3: Client2 <-and Server receives the Hello message
Hello message received
(MessageReceived) LOCK... ...locked
CL[1].UserID:='Client2' <-it's added to the handler
(MessageReceived) UNLOCK... ...unlocked
cl <-I fire 'cl' command and....
(DoHandleCommunication) LOCK... ...locked
Count=2
0 <-...both clients are connected but the Hello message from Client1 never reached Server
1 Client2 so there is no user name.
(DoHandleCommunication) UNLOCK... ...unlocked