I am working on a project where we use signalr to communicate with client. I got the case where client is connected to the server and he is using VPN.
Whenever he lost internet connection he obviously lost connection to hub, but from server side is looking like the connection is still active and OnDisconnectedAsync method is not triggered (half-open websocket?). When he reconnect he is connecting to hub with new connection with different connectionId and old connection is still hanging waiting to be closed.
My question is can i somehow close this connection from server side?
I implemented ping/pong functionality which are sending messages on websocket to client and waiting for response and i want to close this connection if i dont get any message back from client after 30 seconds.
Have you perhaps overwritten some timeout methods?
Take a look at this article from Microsoft: https://learn.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/handling-connection-lifetime-events#timeoutkeepalive
It explains the lifetime of a connection and timeout functionality. Maybe this helps.
Good luck!
Related
I am using latest SignalR version 2.3.0 with C# client.
The problem I am facing is kind of mentioned here on stackoverflow. But that issue is few years old and it is already closed on github.
The issue I am facing is that whenever a request timeout from client to server then client starts reconnecting to server and then keeps on reconnecting. I tried defining the WebSocket protocol also in connection but result is still same.
_connection.Start(new Transports.WebSocketTransport()).Wait(TimeSpan.FromSeconds(10));
I am looking for a persistent connection between server and client.
I have added an event handler on StateChanged event to capture the state changes of SignalR client.
Here's the screenshot of reconnecting state
Does anybody have any idea why it's happening and how it can be prevented?
The reason might be because your OnReconnect even doesn't fire and then again your OnDisconnected doesn't fire when the client calls the `stop method as described here:
If the client goes into reconnecting mode but can't establish a
transport connection within the disconnect timeout limit, the server
terminates the SignalR connection. When that happens, the server
executes the Hub's OnDisconnected method and queues up a disconnect
message to send to the client in case the client manages to connect
later. If the client then does reconnect, it receives the disconnect
command and calls the Stop method. In this scenario, OnReconnected is
not executed when the client reconnects, and OnDisconnected is not
executed when the client calls Stop.
This is referring to SignalR version 2, But I believe that it will of help to you as well.
Worth mention as well, that you will contentiously try to reconnect if you call start from your closed event (or disconnect in JavaScript`) as said:
In some applications you might want to automatically re-establish a
connection after it has been lost and the attempt to reconnect has
timed out. To do that, you can call the Start method from your Closed
event handler (disconnected event handler on JavaScript clients). You
might want to wait a period of time before calling Start in order to
avoid doing this too frequently when the server or the physical
connection are unavailable. The following code sample is for a
JavaScript client using the generated proxy.
anyway, the simplest way to disconnect your client from the server up until version 2 is to implement the disconnect method on the client an call it from the server as mentioned:
SignalR version 2 does not have a built-in server API for
disconnecting clients. There are plans for adding this functionality
in the future. In the current SignalR release, the simplest way to
disconnect a client from the server is to implement a disconnect
method on the client and call that method from the server.
I have a tcp server that writes in winforms and a client in android. I connect devices to a wirless network then I disconnect server from this network. However client continue to listen server for a while then it closes its socket. How can I tell client to close socket when server is disconnected from network?
The reason it happens (if I understand the problem correctly) is that there is not inherent way to know that a connection has been closed, unless you try to send a package. So in your client, if you try to send an empty package over the connection, it will immediately report if the connection has been closed.
This is the reason that Heartbeats exist, and you can configure your socket to use them, or you can have your client periodically (or when needed) attempting to send an empty package and report the status of the connection.
There is an excellent article on CodeProject about this, see here.
Imagine some spherical horse in a vacuum:
I lost control of my client application, maybe some error has happened. And I tried to re-enter to the hub immediately.
Is it possible, that OnConnected starts faster then OnDisconnected and I turn up twice on the server?
Edited:
Sorry, I didn't say than I meant SignalR library. I think if my application won't call stop() the server will wait about 30 seconds by default. And I can connect to the server again before OnDisconnected is called. Isn't it?
You'll have to take it from the client's side, also note that if you're using TCP the following would take place:
TCP ensures that your packets will arrive in the order they were sent. And so let's imagine that at the same moment the "horse" hit the space and the connection broke, your server is sending the next packet that would check the connection (if you implemented your server good enough that is).
Here, there's two things that may happen:
The client has already recovered and can respond in time. Meaning the interval in time when the connection had problems was small enough that the next packet from the server hasn't arrived yet. And so responding to your question, there's no disconnection in the first place.
The next packet from the server arrived but the client is not responding (the connection is severed). The server would instantly take note of this, raising the OnDisconnected event. If the client recovers virtually at the same time the server takes note, then it would initiate another connection (OnConnected).
So there's no chance that the client would turn twice. If any, the
disconnection interval will be small enough for the server not to
notice the problem in the first place.
Again, another protocol may behave differently. But TCP is will designed to guarantee a well established connection and communication between a server and clients.
It's worth mentioning that many of the communication frameworks (if not all) use TCP implicitly by default.
A client can connect a second time while the first connection is open (it will have a separate connection id though).
If the client doesn't manage to notify the server that it's closing the connection, the server will wait for a certain amount of time before removing the connection (DisconnectTimeout).
So in that case, if you restart the connection immediately, it will be a new logical connection to the server with a new connection id.
SignalR will also try to reconnect to the existing connection when it is lost, in which case it would retain its connection id once reconnected. I would recommend reading the entire article about SignalR connection lifetime events.
For the case of an SignalR client using .Net Framework 4.0 to connect to the server (therefore no WebSockets transport supported) which would be the next fallback transport ?
Moreover, if there is a fallback chain it would be great to know it.
From https://learn.microsoft.com/en-us/aspnet/signalr/overview/getting-started/introduction-to-signalr#transports-and-fallbacks the following are used if WebSockets is unavailable:
Server Sent Events, also known as EventSource (if the browser supports Server Sent Events, which is basically all browsers except Internet Explorer.)
Forever Frame (for Internet Explorer only). Forever Frame creates a hidden IFrame which makes a request to an endpoint on the server that does not complete. The server then continually sends script to the client which is immediately executed, providing a one-way realtime connection from server to client. The connection from client to server uses a separate connection from the server to client connection, and like a standard HTML request, a new connection is created for each piece of data that needs to be sent.
Ajax long polling. Long polling does not create a persistent connection, but instead polls the server with a request that stays open until the server responds, at which point the connection closes, and a new connection is requested immediately. This may introduce some latency while the connection resets.
Update:
The latest docs are available here: http://www.asp.net/signalr/overview/signalr-20/getting-started-with-signalr-20/introduction-to-signalr
I'm working on a C# WebSocket server (currently supported by https://datatracker.ietf.org/doc/html/draft-ietf-hybi-thewebsocketprotocol-17).
The server is working with the Socket object of the .NET for the server to listen and for each client to send and receive messages.
I built a web client that connect to the server, It can connect successfully and i can send messages between clients.
Everything is working great!
Now, if i'm connecting to the server and leave the client for a while without sending messages, the server throwing an exception that says:
Int32 Send(Byte[], Int32, Int32, System.Net.Sockets.SocketFlags):An
existing connection was forcibly closed by the remote host.
The exception, as you can see is from the Send method of the client socket in the server, this is looks very wired because i didn't sent any data from the client and no one sending data to this client back so how can it be that the Send method can throw an exception and why this exception is thrown?
It's called a timeout!
WebSockets are just a wrapper around TCP/IP raw sockets (Socket class in .NET) - which timeout if nothing is sent, and nothing is keeping the connection alive.
AFAIK currently the WebSocket API isn't very well defined as far as how to keep the connection alive. I was experiencing the same and had to just switch over to using a ping (empty message) to keep the connection alive (I'm using the Microsoft sockets implementation).
If you're reinventing the wheel for a non final spec, just remember that you'll have to keep reinventing it every time the spec changes. I specifically chose to use the Microsoft sockets preview so that when it's released I'm pretty much not going to have to change any code. I don't run in IIS - I run as a console app and it's working mostly great so far but I have very very few users.
Note: The problem i was having that led me to find this question was if I send 10 messages without receiving a reply then the connection is closed. I'm still looking into why this is - whether its a bug / feature of WebSockets or a feature of the Socket class. it's possible I'm hitting a 65kb limit but my messages are small and I don't think that's why. Just be aware of this when testing whatever you're working on becasue it gives the same error you got.
I assume that you have exclude the usage of different protocols between the servers and the clients (silly assumption, but you never know).
If your code reaches the Send method without a prior Receive from the client, then it's obvious that something is wrong with the server code. Use trace and/or log to get more information even for abc's like entering wait to receive, receiving, received, exiting receiving etc.