Forum > Networking and Web Programming

LazWebsocket How to identify IP adress during connect

(1/3) > >>

hgbk:
I have implemented a game as client server solution using LazWebsockets. It may happen that during the game the connection from a client breaks. In order to implement the possibility for this specific client to reconnect I need to identify the IP address during accept and compare it with ACommunication.SocketStream.RemoteAddress.Address of this client  which I have stored before failure. In accept I have TRequestData as parameter which delivers Host (Domain but not IP address). Any idea how to solve this?

Warfley:
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

hgbk:
Understand - I will implement the "reconnect" according to your proposal. Thanks a lot for the quick and helpful answer!

r.lukasiak:

--- Quote from: Warfley on April 21, 2021, 03:02:55 am ---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

--- End quote ---

Hi everyone!
I've been trying to figure out how to use LazWebSocket for some 3 days. I'm analyzing the example  server and client files. I managed to figure out how the client works (at least some basic functions), I created some basic GUI and applied the "client" code to it, I was able to run it iin StartReceiveMessageThread mode. My app is able to sent and receive the message (OnReceiveMessage). But when I run more than 1 instance, messages from the server are sent randomly. I even tried to start my client app from different IPs, local 192.168.x.x and through HamachiLogMeIn 25.x.x.x. Both instances can send messages to the server but the server answers randomly. I understand that it may happen when there are more than 1 client with the same IP but if 2 clients have a different IP address?
How can I make the server answer to a specific client?

--- Quote ---you could generate a game ID, which every client gets
--- End quote ---
how could I use a client ID to make the server contact the specific client by his ID, not IP?

thanks for any hint.

Warfley:
In LazWebsockets the connection is handled by the TWebsocketCommunicator instance given as Parameter to the handler.

If you want to handle multiple connections, you need to identify these. The (threaded) base handler already provides a list of all connections, you could use the index to identify these:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---  procedure TSocketHandler.IdentifyClients;  var    ConnectionList: TConnectionList;    i: Integer;  begin    ConnectionList := Connections.Lock;    try      for i := 0 to ConnectionList.Count - 1 do        ConnectionList[i].WriteStringMessage('You are client number ' + i.ToString);    finally      Connections.Unlock;    end;  end;
The problem here is, when a client disconnects, it changes the indices of all clients connected after that one (as all move by one). So you could rather than that generate an ID (e.g. by simply having a counter counting up) and use a TDictionary or TFPGMap or similar to manage the connections. You might also need a reverse lookup to map the communicator to it's ID (some extendibility option for the communicator might be also useful here, to store such data right in the communicator).

Another solution is, each handler call gets executed in their own Thread (assuming you use a threaded handler). The best way is to have all the communication happen within that handler and you interact though messages in a message queue. When you receive something you can send a message to the GUI to handle the data. When the GUI wants to send something it sends a message to the handler.

But: no matter what approach you choose, you must always make sure to use sufficient thread locks. All the default  datastructures (arrays, Lists, Maps, Dictionaries, etc.) are not thread safe, so when dealing with the threaded websockets, you should always use locks

Navigation

[0] Message Index

[#] Next page

Go to full version