How do I detect when a client is failing to connect (or re-connect) to a Signalr hub?
Is there an event that fires on the js client?
Responding to your second comment:
Currently in 0.5.3 SignalR does not handle the case when the server goes away. However, this will be/is handled in the next release 1.0alpha.
For the interim I'd recommend pinging the server every 5 seconds and seeing if the request fails. If it fails say 2 times then chances are the server is down and you can handle the logic from there.
If you'd like to see how we do it in the next release here's the link to the github feature: https://github.com/SignalR/SignalR/issues/469
Related
Steps to reproduce
Start server
Send a client RPC to server
Restart server
Using the same client, send another RPC. The call will fail
Send another RPC, this call will success
Also I found that if the server is leave stopped for a long time before starting up again, the call in step 5 will return "channel is in state TRANSIENT_FAILURE" as well.
Example code: https://github.com/whs/grpc-repro
(Install from requirements.txt then run main.py)
Expected result
All call should success.
Tested with Python grpcio==1.19.0 server/client and with go-grpc server. I tried setting grpc.max_connection_age_grace_ms, grpc.max_connection_age_ms, grpc.max_connection_idle_ms, grpc.keepalive_time_ms, grpc.keepalive_permit_without_calls but they doesn't seems to help.
The question is duplicated with https://groups.google.com/forum/#!msg/grpc-io/199V_iF0NMw/NahHz_vMBwAJ.
The feature you want probably is "wait_for_ready". In case of TRANSIENT_FAILURE (server not available temporarily), it will automatically wait for the channel become READY again without failing. Read more about wait for ready.
I have a Spring mvc application, and I'm using websockets to communicate a phisical device that sends data with an angular 2 front end.
the architecture is like this
device ----> Spring Mvc <-----angular 2 front end
I have a datasource listener that publish to a websocket topic everytime a new message appears and I consume that topic from angular.
My problem is that this is working properly in my local tomcat install but when I upload it to a faster server it doesn't.
The main problem I'm having is that is buffering the messages and is reaching the limit and closing the websocket session.
What I noticed checking the logs is that in my local server messages come 20 milliseconds after last one is finished but in the other server sometimes are coming at the same time and they are being buffered throwing the session limit exception.
I tried setting a higher buffer size.
Also tried a thread.sleep but it doesn't worked.
Do you have some ideas what can I do ? should I implement some kind of message queue ?
Thanks in advance
If "OnConnected" is raised when the 1st time we connect to our website, when will "OnReconnected" happen?
1) Suppose someone is connected to the network and suddenly the network isn't available and soon it recovers, so OnReconnected happens?
2) Any other special that will make OnReconnted happen?
Thanks!
The Signalr documentation on Understanding and Handling Connection Lifetime Events in SignalR should have all the information you need.
Generally speaking OnReconnected will fire any time the SignalR client automatically reconnects to the SignalR server after it has lost its connection for any reason. These reasons can include network issues, the server restarting, etc...
The SignalR client will stop attempting to automatically reconnect to the server if it is unable to successfully do so within the DisconnectTimeout. If this happens, and you want to reestablish a connection, you will be required to manually restart the client by calling start() after the client becomes disconnected. If you manually restart the client by calling start(), OnConnected will be called instead of OnReconnected and the client will receive a new connection id.
My understanding of the (JavaScript) hub client is that if a connection is lost, it enters a 'Reconnecting...' phase which attempts to reconnect. If it can't do so, it will enter a 'Disconnected' state which is where it'll stay until asked to start again.
How long is the 'Reconnecting...' phase meant to last before it gives up? I've read 40 seconds before, but my client seems to take much less time - about 10, maybe less. [EDIT: Nevermind this part, I had configured a 10 disconnect on the server as a test... and forgot. I understand this is set by the server during the negotiate. Makes sense!] ... I'd prefer to have the client continually retry until it is told to abort - can this be done, and would it cause issues?
Another question; during the Reconnecting... phase, if I attempt to call a hub method (again, in JS) it never seems to complete. I'm using the returned Deferred to check for 'done' and 'fail' events, but neither seems to get called. Is this by design?
Thanks.
You can definitely have it continually reconnect.
Handle the disconnected event on the client and call connection.start:
$.connection.hub.disconnected(function() {
setTimeout(function() {
$.connection.hub.start();
}, 5000); // Re-start connection after 5 seconds
});
The only issues this would cause is that you could potentially be triggering infinite requests to a server that isn't there for client machines. This becomes even more troublesome when you introduce the mobile market into the situation (drains battery like crazy).
When you attempt to call a hub method while reconnecting SignalR will try to send your command. Since there are 2 channels, one for receiving data and one for sending, (for all transports except web sockets) in some cases it can still be possible to send requests while your offline. Therefore SignalR does not know if a request fails until the browser tells it that it could not successfully make the request.
Hope this helps!
I might have a clue... Touching the Web.config produces an appPool Recycle, meaning that a new worker process will be created for new requests while the existing process will continue for a while until the remaining requests end or the timeout is reached. Request that do not end in the timeout period are terminated.
Signalr client reconnects to the new process while the long running task is running in the old process, so when on the long running task you do
GlobalHost.ConnectionManager.GetHubContext<ForceHub>();
you actually get a reference for "old" hub while the client is connected to the "new" hub.
That's why the test preformed by Wasp worked: he was making a new request to publish on the signalr hub that was processed in the newly created worker process.
You could try to configure a singalr backplane (https://www.asp.net/signalr/overview/performance/scaleout-in-signalr), it’s really easy to configure it using Sql Server (https://www.asp.net/signalr/overview/performance/scaleout-with-sql-server). The backplane should be capable of connect the two worker processes and hopefully you will get the notification on the client.
If this is the problem, notifications generated by new requests will work even without the backplane. Notice that the real purpose of the backplane is to scale out signalr, this is, to connect a farm of WebServers between them.
Also keep in mind that running long-running task inside IIS is as task hard to achieve as, among other things, IIS does regular appPool recycles and has timeout limits for the requests to execute. I recommend that you read the following post: http://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx
“If you think you can just write a background task yourself, it's likely you'll get it wrong. I'm not impugning your skills, I'm just saying it's subtle. Plus, why should you have to?”
Hope this helps
The blazeds server-side don't know the client-side has disconnected. But it seems to know the client-side's network has down.
In my case, I use the polling channel, I download the blazeds's source code, and add some log output in the FlexClientOutboundQueueProcessor.flush(MessageClient messageClient, List<Message> outboundQueue) method.
Then I saw this, when a client subscibed, the server-side invoke the FlexClientOutboundQueueProcessor.flush method every 3 seconds, and print what I added in the flush method, then I only shut down the client's network, not close browser(client and server with difference network), I found the server-side don't print anything, it means that the server-side don't invoke the flush method.
And after more than 30 minutes I recover the client's network, the server-side continue to invoke the flush method (the client's session isn't destroyed, if I close the client's browser, after 30 minutes the server-side will destroy the session).
Now, I have two questions,:
How the server-side know the client's network has downed? Is there a listener to monitor the client's network? If so, where is it? If not, how and where the codes?
It seems that the server-side will invoke the FlexClientOutboundQueueProcessor.flush method every 3 seconds, can this interval be configured? And where the code to start or stop this timing task?
Here answer on your first question: Detecting (on the server side) when a Flex client disconnects from BlazeDS destination
About configuration. You can configure in services-config.xml.
Example BlazeDS applications
Configuring channels with servlet-based endpoints