Testing if a socket is still open isn’t as easy at it sounds. Anyone who has ever dealt with socket programming knows this is hassle. The general pattern is to poll on the socket to see if its still available, usually by sitting in an infinite loop. However, with f# this can be done more elegantly using async and some decoupled functions.

First lets write an async function that monitors a socket and returns true if its connected or false if its not. The polling interval is set to 10 microseconds. This is because if you set the interval to a negative integer (representing to wait indefinitely for a response), it won’t return until data is written to the socket. If, however, you have a very short poll time, you will be able to detect when the socket is closed without having to write data to it.

  
/// Async worker to say whether a socket is connected or not  
let isConnected (client:TcpClient) =  
 async {  
 return  
 try  
 if client.Client.Poll(10, SelectMode.SelectWrite) && not \<| client.Client.Poll(10, SelectMode.SelectError) then  
 let checkConn = Array.create 1 (byte 0)  
 if client.Client.Receive(checkConn, SocketFlags.Peek) = 0 then  
 false  
 else  
 true  
 else  
 false  
 with  
 | exn -\> false  
 }  

Next we can create a simple monitor function to check on a predicate, and if the predicate returns false (i.e not connected) it’ll execute an action. Otherwise it’ll call itself and monitor the socket again. This is important since the poll will exit once it determines that the socket is connected or not.

  
let rec monitor predicate onAction client =  
 async {  
 let! isConnected = predicate client  
 if not isConnected then  
 onAction client  
 else  
 return! monitor predicate onAction client  
 }  

Then, to use the monitor function all you have to do is something like this

  
monitor isConnected onDisconnect client |\> Async.Start  

Where monitor is the generic async monitor function, isConnected is the async socket poll, onDisconnect is a function to call when a client disconnects, and client is a tcpClient socket connection. The great thing about this is that you don’t need to have a seperate thread for each open connection to act as a monitor/handler.