I'm using SignalR (0.5.3) Hubs for a chat app where each keystroke is sent to the server (saved in the DB), relayed to all clients and a return value (a string token of sorts) is sent back from the server.
It works fine, until the app pool recycles, then it stops relaying the keystrokes to all the clients (because the in-memory server state is lost I suppose) and the server doesn't return back any values as well. At this point, I suppose all requests via SignalR are queued by IIS and then processed once the app pool has been recycled.
My question is how can I handle this scenario so that all clients are aware of the server unavailability/delay due to app pool recycle, notify the user to wait for a while and then resume operation on reconnect?
There's two options.
For 0.5.3 you can detect when the client goes into "reconnecting" or is "disconnected" and notify the user that there is server issues. Keep in mind in most situations the client will not actually know that it is disconnected if the server just goes away.
OR
If you wait for the next release (1.0alpha) we will take care of the bulk of this for you. On lack of a server we will trigger an onConnectionSlow event which will then result in the client shifting into the "reconnect" (if it does not receive any info) state until the server comes back online. The client will also know if the server goes away (we're adding this functionality) for edge cases such as an app pool recycle.
Hope this helps!
Related
1- Client application sends a a request to an http server (ashx file, IHttpHandler).
Remark-1: Client is a .dll which will be hosted by other stand alone applications.
Remark-2: Server was first developed as a web service, then for unknown reasons it became very slow, so we implemented it from scratch.
2- Server registers the request in database so that a long duration process is performed on data.
3- Client needs to get notified when the process is finished.
First thing that crossed my mind was implementing a Timer in client. Although I'm not sure if it is ok to do it inside of a host application which is not aware of such usage.
Then it crossed my mind if there may be a something useful in TcpListener or lower layers of socket programming instead of a high frequency timer and flooding server with update requests.
So, I appreciate any suggestion on proper way of doing this task.
UPDATE:
After giving some order to my codes, I update requirements like this:
1- Server "Broadcast"s ID of clients, like: "Client-a, read your instructions", then "Client-c", "Clinet-j",... . This is not mission critical, if a client looses the broadcast, it will return after one minute by a timer tick and will check instructiosn.
2- This server is gona be hosted on a shared hosting plan, at least at first. Solution must be acceptable in boundary of share hosting.
3- preferably all clients connect to the only one socket. No usage of extra resources.
Any recommendation is appreciated.
I have a game server system that has a sslstream module and reads/writes using async calls. The server holds up great, functions perfectly fine, however, after a period of increased traffic the user's SSL simply stops receiving on the server end.
However, the client still gets sent data, and sends data fine, for them it seems like the game still works fine for them until they can't deal damage.
No other users are directly effected at the time, all other streams continue along (unless they also hit the same bug), resetting the connection will restore the to a functioning state.
As far as I can tell from debugging:
The Socket remains active (Until the server initiates an inactivity drop)
Only Server side receiving is ever effected
Increasing the amount of data sent does increase the likelihood of the issue occuring
No Exceptions are thrown, the stream still shows an ability to read/write
The stream can still successfully send to the client
Terminating the client's connection will send through the normal 0 length termination 'read' on the client
Does anyone know what would cause this? (also possibly worthy of note, the system also can be booted up with a straight TCP socket, and it runs flawlessly with that. The issue only occurs when using the SSL stream)
My system is composed of
SignalR server
Multiple C# clients connecting to said SignalR server.
As I understand, once connected each of these clients would have its own associated ConnectionId.
Now, I want to implement a resiliency strategy where after the SignalR server is restarted, it should still retain the Groups and Connections it used to have in the Hub.
I was thinking of achieving this by storing the Groups and ConnectionIds in an external storage (e.g. database), and restore it when the application starts up.
When the server goes down, the clients' connection might have dropped. But this can be mitigated somewhat by making the client always attempt to reconnect on disconnection. Once the server is up, the client would reconnect.
However, this solution feels rather flaky. In particular, I'm not sure whether once the client reconnects it will retain the same ConnectionId.
Does this approach make sense? Is there a better way to do it?
Yes, client-reconnects ALWAYS happen with the same connectionID. The connectionID is renewed ONLY in case:
the connection.stop() method is called from the client,
the server has detected client disconnection and does a disconnect on the server + sends a disconnect message to clients that happen to reconnect too late. Then those clients will close connection. So client-server are synced again.
If the client is connected to a server that is about to reboot, the clients will notice upon disconnection and try to reconnect to the server with the same connectionID, all within a given timeframe, defined by the connection-timeout. If the server, then, reboots within the connection timeout frame, the client reconnects to the server, with the existing ID.
In this case the Reconnect() event is fired on the server, without the OnConnected() event is happened. This is an exceptional signalr case.
Code your Reconnect() events very defensively.
link to official documentation explaining this issue
chapter: Server disconnection scenarios
I'm currently evaluating using asp.net websockets for connecting a few thousands clients that will stay connected with the app pretty much 24x7, except for when the server goes offline for patching etc. Generally, the expectation from the system is that websockets should not disconnect unnecessarily and the clients will basically stay connected and ping the server every few mins.
While I was researching asp.net websocket viability for our new architecture, I came across another stackoverflow post: IIS App Pool cannot recycle when there is an open ASP.NET 4.5 Websocket which seems to suggest that IIS doesn't recycle the pool if there is an active websocket connection. Is this by design or did the other person experience an anomaly? If IIS does recycle the pool while the websocket connections are active, what's the expected behavior? Does Http.sys keep the connections, recycles the pool and things resume as if nothing happened (from the client's perspective)? Should I just create a separate app pool for websockets and disable recycling on it?
From my experience no, the WebSockets on the old worker process are not transitioned to the new worker process. I have observed that the old WebSockets are put into a non-Open state and it is up to your code to check this and stop maintaining those threads - my application was creating a heartbeat to the client over WebSockets and if the heartbeat failed I needed to close that (already closed) WebSocket context as soon as possible so the old worker process could fully unload and die.
I have created a small application which log data from client to server. I want to get the status of client application when it exit the application from task messenger. How do i get the client status.
Just like in skype.
I user exits skype form task messenger another user's skype shows got logged out this user.
You could have the client send small heartbeats in regular intervals. If those heartbeats stop coming you know that the client has shut down (either the process was killed, the application shut down, the computer shut down, the network connection dropped, etc...).
Cant you catch SocketException and also check for receiving zero bytes. If you receive zero bytes the other side closed the connection cleanly. If you get a SocketException with the SocketErrorCode set to ConnectionReset then you can also assume the other side is gone. The only thing you won't pick up is half open connections. For that you will need some sort of keep alive packet as Andreas suggested.