I am implementing a TCP Server in Erlang which talks to mobile phone clients.
Mobile phones get offline a lot, so the server must be able to detect it.
Hence I want the server to send messages to clients with a timeout, so that when the timeout
happens the connection is closed and the client are marked offline.
I used this listen option on the server:
[{certfile, "cert.pem"},
{keyfile, "key.pem"},
{reuseaddr, true},
{active, false},
{send_timeout, 10000}]
After I set up the connection between the server and the mobile phone, I switch the phone to airplane mode(which shuts down all wireless signals), and do an ssl:send on the server. The send function happliy returned ok as if the packet is successfully transmitted.
What have I done wrong?
Did you set the {send_timeout_close, true}
parameter on the socket from inet
? If not, the socket won't be closed, just return back a timeout error. There is also the risk ssl
swallows your error and does something with it.
Some other points:
Remember to check the return value of any ssl:send
and ssl:receive
options for error. It is important to know that the send went well.
ok = ssl:send(Sock, Data),
The underlying TCP/IP stack might actually accept the data even with a send_timeout
set, but won't be able to send it as the other endpoint is down. The knowledge of the closed port first arrives later on, when the stack realizes it never got an ACK.
There is a raw
entry type for Sockets, defined in inet
. It allows you to set OS-specific socket options. It may be possible to coerce the OS into being more aggressive at detecting the loss of a connection.
Another option is to cue everything on a ssl:recv/3
call where a timeout signifies loss of the device, regardless of its socket status. It has the advantage of also detecting application trouble in the other end as it does not progress along the determined path. You will have to do this for processing further requests anyway.
The mobile phone client can also act. If it send's a message over SSL and the receive never arrives (due to airplane mode) - then it knows something is wrong. The server may not know this however.
TCP/IP provides a reliable, connection-oriented stream protocol. It does not guard against sudden disconnects. This is important as your protocol must handle the disconnect problem itself. It is especially important if your protocol has some kind of confirmation or acknowledgement.