Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SignalR: How to stop creating new connection on page reload

Hi i am developing a chat application along with some other pages in my application. once i login i am maintaining the session of the user. My main intention is that user should get notification whenever another user connects to server.

The problem that i am facing is whenever i navigate to some other page in my application the connection is lost. How to stop this behaviour and continue the connection until user logs out.

I am using SignalR 2.0 in ASP.NET MVC4 project, any help??

like image 267
Saurabh Sashank Avatar asked Nov 27 '13 04:11

Saurabh Sashank


People also ask

How do I stop SignalR connection?

A SignalR connection can end in any of the following ways: If the client calls the Stop method, a stop message is sent to the server, and both client and server end the SignalR connection immediately.

How do I set SignalR connection timeout?

Configuration. ConnectionTimeout = TimeSpan. FromSeconds(40); // Wait a maximum of 30 seconds after a transport connection is lost // before raising the Disconnected event to terminate the SignalR connection.

Does SignalR require sticky session?

SignalR requires that all HTTP requests for a specific connection be handled by the same server process. When SignalR is running on a server farm (multiple servers), "sticky sessions" must be used. "Sticky sessions" are also called session affinity by some load balancers.

How many connections SignalR can handle?

In the default mode, the app server creates five server connections with Azure SignalR Service. The app server uses the Azure SignalR Service SDK by default. In the following performance test results, server connections are increased to 15 (or more for broadcasting and sending a message to a big group).


1 Answers

Each connection only has a lifecycle for the duration of the time the user spends on a given page. When they navigate to another page, a new connection is established. Also, if a user has more than one tab or browser window open, they will have multiple connection Ids. I don't think you want to try to persist the connection Id beyond it's intended lifecycle.

In a similar scenario that I work on, we store the connectionIds OnConnect and delete them OnDisconnect. When a message needs to be sent to a given user, we send it to all of their connectionIds. This ensures that the message will be delivered to all tabs/windows.

EDIT 1 the following is in response to @Saurabh's comments:

Consider what the scope of the Hub is, and that of your other classes and the client. The Hub is there to facilitate communications between the browser and the server. While it's possible to do a lot of work within the hub, I think it's best to move most of the scope outside of communictions to other places.

The client knows that it just reloaded a page, so it's a good candidate for making the decision that this is a reconnect event.

_chatHub.server.reJoinRooms();

Then the Hub can query the user's rooms, by UserId, rather than ConnectionId.

public Task ReJoinRooms()
{
// get the user's rooms from your repository
// optionally get the user's connectionIds from your repository
// Clients.Caller.onJoinRooms(rooms);
// or Clients.Clients(_connectionIds).onJoinRooms(rooms);
}

Then the client can decide whether or not to take action:

$chatModule.client.onJoinRooms = function (rooms) {
   for (var i in rooms) {
           var _room = rooms[i];
           // if I'm not already in this room, add it to my rooms
           console.log('joining room', _room)
       }
}

You could skin this many different ways. The client could own the scope of remembering rooms, instead of a server-side repository, too.

EDIT 2

If the number of groups/rooms that a user belongs to is ever-increasing, the above example may not scale up very well.

In that case, each user could join personal feed(s) instead (i.e. join a feed named for the user's GUID). We would keep track of each user that is affiliated with a group. When a message is sent to that group, we would iterate over those user's and publish a message to each feed.

like image 71
andes Avatar answered Sep 29 '22 04:09

andes