Does signalR backplane shares the connection information also?
I mean in case of "longpolling" the connect request goes to one server and start server goes to another server then it gives this error
"The ConnectionId is in the incorrect format."
I am believing that this error is coming because the instance on which this request is going does not have any information about this connection id. I am using SQL server backplane but still facing this problem.
We are not supposed to use sticky session in our production environment
No, SignalR doesn't share any information regarding client connect\disconnect over the backplane (for example - server2 is not notified about new client connections on server1)
So the problem is somewhere else...
I got the problem. Its machine key issue only.
I had to explicitly add machine key in web.config of my application.
Then it is able to unprotect the token which is generated by another instance of my application.
Now its working fine.
Related
While trying to connect to SQLAnywhere (Sybase) database (C# code) from Azure ServiceFabric:
await using var connection = new SAConnection(connectionString);
await connection.OpenAsync();
receive iAnywhere.Data.SQLAnywhere.SAException
Connection error: Connection was dropped (may not be a SQL Anywhere server)
Error code is Error 832. This is generic connection error: An error occurred while attempting to establish a connection with the database server, but before attempting to connect to a database. Failure to initialize a communication link during the connection attempt is an example of this error. Creating a debug log file using the LogFile connection parameter may provide more information.
Locally it works, but does not work from Service Fabric.
Fix ideas tried:
Missing driver? Looks like no, Sybase (now SAP) SQLAnywhere requires special driver or client - but locally also works without this driver, just with iAnywhere.Data.SQLAnywhere.NETCore nupackage installed
Network connection/ firewall problems? Looks like no, database server can be pinged from Service Fabric node
It was another traffic protection tool. Although it was possible to telnet the port, still traffic from app was blocked by another tool.
Had a similar issue - turned out that whilst standard incoming traffic from the Sybase Server had been whitelisted in our Firewall, encrypted traffic from this had not been.
This meant I could ping and connect with Telnet, but got the same error when trying to log-in with my credentials
Connection error: Connection was dropped (may not be a SQL Anywhere server)
Our comms team solved the issue by whitelisted encrypted traffic from the server address as well. They also mentioned it possibly could have been solved we shared a valid security certificate for the encrypted data with their team, but were happy with the first course of action.
I'm using SignalR and a web farm in IIS, currently with 3 servers and requests are load balanced via ARR.
There are certain external events that happen which I want to be processed by the server to which the client is connected. So I want to track which of the 3 servers the client is currently connected.
I thought that I could do this using OnConnected and within that method store the MachineName against the ConnectionID in redis.
The problem is that OnConnected seems to get called an a different server to the one that the client is connected to.
Upon investigating, it seems that there are three calls, one to /negiotate one to /connect and one to /start. The /connect seems to be the websocket connection that is kept up for the duration, the others are just transient.
These three connections can happen on different servers, and it seems that the websocket connection can be to server A (so that's the server that the client's SignalR connection is going to), but the OnConnected gets fired on server B.
I was wondering if I'm overlooking something that will let me see which server the SignalR connection is actually connected to?
Thanks,
Will
If you are going to use a web farm, then you need to implement a backplane to track all of the messaging.
https://learn.microsoft.com/en-us/aspnet/signalr/overview/performance/scaleout-in-signalr
Without a proper backplane implementation its impossible to do what you want to do.
I believe that is something you would have to save. Assuming you are using a database for mapping users, you could have an additional field such as "LoggedInOn" and store the server host name or other identifier.
However, other than some aspect of troubleshooting your are looking to do, proper send/receive of messages should cross the backplane to all servers. This way no matter which server they are connected to, messages are received.
If you have external events as you say, once they complete and a message is ready to be sent back to a client, the backplane should push that to all servers.
If that's not happening I would review the docs as Kelso Sharp stated.
My current solution is ,I have a load balancer and behind that I have implemented a backplane (SQL Server) in order to support scaling . Along with that, I want to have redundancy as well . Example if server 1 goes down all the connected connection in that server should connect to other servers .
Will the standard SignalR Backplane solve this problem ? Or else is there other good approaches ?
If you have a backplane and a loadBalancer it should work. If a node dies clients will try to reconnect and if the load balancer redirects them to a different node that is using the same backplane they will be able to reconnect fine. One important thing in distributed scenarios - all nodes have to have the same machineKey otherwise requests will be rejected because the node will not be able to decrypt the connection token.
Using SignalR, it's designed to maintain a long-running connection to the web server. However, I have a scenario where the SignalR connection maintains an open connection to the web server, long after the ASP.Net session has expired. This happens even though neither the client nor the server is sending an data.
How can I set things up so that once the Asp.net session expires, the SignalR connection terminates, freeing up connections on the server?
This is desired because the web servers run on a load balancer, and when taking a server out of the rotation, we need the # of current connections to generally represent the number of active sessions - not SignalR connections that are still kicking just because user left browser open.
SignalR Server does not allow to disconnect a particular client connection (this would be super useful). So the client is responsible to do that.
A workaround would be to add an event listener on the client and disconnect from there, i.e:
hubProxy.On<string>("YouAreUselesLetMeAlone", _ => connection.Dispose());
Obviously, to make this work you need a relation (ConcurrentDictionary?) of asp.net sessions <-> signalr connections, so you can call this method in the correct client when the asp.net session ends.
Makes messaging on SignalR. Client - .NET 4.5 local application.
I do not know how to check the status of the connection with the client on the server side. The fact is that when connecting the user logs in the server. And if you disable a user account is deleted from the server.
If the client application is not completed normally, for example as a result of exceptions, On Disconnected method on the server is not called, and the user account is not deleted.
Tell me how you can solve the problem, if anyone knows.
I read somewhere that SignalR is smart enough to handle disconnection and remove the disconnected client from the group automatically, so no need to worry about the anormal disconnect events.