Monitoring and Controlling DataSnap TCP/IP Connections
Go Up to DataSnap Server Application
Starting with RAD Studio, DataSnap servers with TDSTCPServerTransport components are able to monitor connections and close any TCP connection they want. The connections are linked with a Session ID, which can be used in a server method or authentication manager to get the TCP connection for the current session. This allows both server methods and authentication managers to terminate a connection for any reason.
Listening for Connections
procedure TForm1.ServerTransportConnectEvent(Event: TDSTCPConnectEventObject); begin //Add both the connection and Channel (TDSTCPChannel) to a dictionary for later use FConnections.Add(TIdTCPConnection(Event.Connection), Event.Channel); end;
The previous code snippet captures and stores the Channel, which is an instance of TDSTCPChannel, as well as the connection, for later use. The connection will be provided without a channel in the disconnect event, so in a way it can be used to uniquely identify a channel. The channel has a GetConnection function, which will return its connection, if needed.
Listening for Disconnects
An implementation of the OnDisconnect event may look like this:
procedure TForm1. Server TransportDisconnectEvent(Event: TDSTCPDisconnectEventObject); begin //Remove the connection and its associated channel from the dictionary FConnections.Remove(TIdTCPConnection(Event.Connection)); end;
The previous code snippet is called whenever the TDSTCPServerTransport component is still active and a TCP connection has been closed. If the transport is being disposed, then this event will not be notified. Note that the event provides only the connection, but this connection could be used to look up a channel you have obtained with the OnConnect event.
Detecting Graceless Disconnects
By default, the OnDisconnect event will not be notified if the client abruptly loses the Internet connection. This is because the socket remains open until an IO operation is attempted and fails. If your OS is configured to use keep-alive packets for all TCP/IP connections, then, based on its configuration, you will eventually see the disconnect event being notified. If you want to control this behavior on a per-connection basis, then you can use the EnableKeepAlive and DisableKeepAlive methods on the TDSTCPChannel:
//If the connection is idle for 10 seconds, then send a keep-alive packet to check whether the client is still there. Event.Channel.EnableKeepAlive(10000);
The previous code snippet will enable keep-alive for the specific channel or connection. This will send a keep-alive packet to the client whenever it has been idle for more than the specified time (10 seconds). If the client does not respond, then the packet will be resent a number of times, as defined by the Operating System. (For example, in Windows 7, it will retry 10 times.)
There is an optional second parameter to the EnableKeepAlive procedure, which is an integer representing the number of milliseconds to wait between retries if a client does not respond to a packet. If undefined, it defaults to a value of 100 milliseconds.
If you want to disable keep-alive for a specific connection, then get the Channel instance and call DisableKeepAlive.
Closing a Connection
You can close a connection at any time by getting the connection's channel, and calling its Close procedure. An example could look like this:
//Get the associated Channel for the given connection and, if successful, close it if FConnections.TryGetValue(Connection, Channel) then Channel.Close;