Azure Websocket Timeouts on Long-Living ConnectionsNovember 10, 2020
I’ve been recently working on a gateway service hosted in Azure that is primarily a TCP server. One of the key requirements of the project is that it allows clients running a desktop-based windows service to initiate a handshake over TCP when their respective service is started, and then keeps a connection open between the client and server for the receipt of messages at any given time.
However, this presented a problem. Azure doesn’t like me doing this.
It seems that Azure apps (Azure Cloud Services in particular, which is what I am using), have an ‘idle timeout.’ According to Microsoft, this is usually between 4 and 30 minutes long, after which time, your client’s connection is removed. Apparently, this is configurable.
So if like me you are using Azure, you should be able to go into the app’s config settings (I believe app.config for app service or Service.Definition for cloud services) and change the idle timeout property on any endpoints you have open on the app like so.
<InputEndpoint name="MyEndpoint" protocol="tcp" localPort="80" port="80" idleTimeoutInMinutes="30" />
The problem for me is, this wouldn’t really fit my requirements as my clients’ connections are still limited to a maximum idle timeout of 30 minutes. I want to be able to allow my clients to start their desktop service and then stay connected indefinitely.
The solution in my case was relatively straightforward. The key thing to note in the timeout that Azure enforces is the word idle. It only times out if the server receives zero data from a client within the defined timeout period. So sending an arbitrary command to the server keeps the connection alive.
So in nearly all cases, when my client sends data to the server, it sends a command which can be interpreted by the server, usually to perform an action and then potentially return a responding command back to the client (not immediately. We’re using WebSockets remember, not HTTP!) But in this case, I can send a command I usually call ‘NOOP.’ (Meaning ‘no operation.) The server would receive this and simply do nothing. This would automatically reset the idle timeout so that the client’s connection is kept alive. You could even change the command to ‘KEEP ALIVE’ and have the server perform other actions based on this if needed. Simply create a task that is called every x minutes and your connection is going to stay up.
It’s important to note that I am not using SignalR. I don’t know if this applies to projects like mine that use SignalR, but if you are using it and this issue is affecting you, I hope this is an adequate solution for you.