I'm concerned about using Clients.All
in my C# Signal R hub class
Clients.All.setConnectionStatus(profileId, true);
I'm calling it in both OnConnected()
and OnDisconnected(bool stopCalled)
to show the online status of my logged in users.
OnDisconnected()
isn't as bad because it's only being called when someone actually logs off
ex.
public override Task OnConnected()
{
string profileId = Context.User.Identity.Name;
_connections.Add(profileId, Context.ConnectionId);
Clients.All.setConnectionStatus(profileId, true);
return base.OnConnected();
}
public override Task OnDisconnected(bool stopCalled)
{
string profileId = Context.User.Identity.Name;
_connections.Remove(profileId, Context.ConnectionId);
if (stopCalled == false) // log off only
Clients.All.setConnectionStatus(profileId, false);
return base.OnDisconnected(stopCalled);
}
My concern -> Blowing up the users machine client side with javascript code constantly running in the browser!
Scenario -> If I have > ~1000 users online and logged in traversing to different pages, I will be broadcasting to all of them a signal R connection Clients.All.setConnectionStatus(profileId, true);
which in the javascript hub looks like this below which could easily end up blowing up the users browser, because it would be constantly receiving these broadcasting connection status calls!!!
scope.chat = $.connection.chatHub;
// Receive and set the connection status
scope.chat.client.setConnectionStatus = function(profileId, isConnected) {
// look for prfileId in html
var $profileStatusElement = $(".online-status-profile[data-id='" + profileId + "']");
var $profileChatElement = $(".online-status-chat[data-id='" + profileId + "']");
if (isConnected === true) {
// change the online status
} else {
// change the online status
}
};
I have chat windows to users (online) like below that shows a users status next to their name. So I know if the person I'm sending a message to is online or not!
When I first load the chatbox, I fetch the online status server side, but after that it's up to the OnConnected()
and OnDisconnected()
methods in my hub to set the online status of the person I'm chatting with.
There's got to be a better way then broadcasting the signal out to 'all' online users on my site? But the only way I can think of is to poll the status every so often on some javascript timer, but I hate that idea!!
Another way would be to keep some kind of in-memory collection of who each person is chatting with, but that seems like it could get really messy and could end up up not being very accurate, being there could be so many things in between the client and server that could cause a disruption to mismanage the in-memory collection of who's connected to whom! Any thoughts or ideas here would be greatly appreciated!!
FYI -> I also have a messages page, that shows a list of all the recent conversations I've had with users like below. And on this page I show the online status of these users as well. On this page I fetch the online status of each user on the server before I render the page, same as the chat box, but once the page is loaded, it's up to the OnConnected()
and OnDisconnected(bool stopCalled)
to set the online status of each user on the page.
You're doing in right way with signalR. I guide you based on your concerns/scenarios:
My concern -> Blowing up the users machine client side with javascript code constantly running in the browser!
Don't forget that you are using a browser underlying functionality (WebSocket), so we have no choice unless running some js code inside client loaded page. You take advantage of browser capabilities here.
Scenario -> If I have > ~1000 users online and logged in traversing to different pages, I will be broadcasting to all of them a signal R connection
Clients.All.setConnectionStatus(profileId, true);
Before proposing any solution, I exhort you to employ grouping logic in your application. Grouping reduces the volume of synchronizations.
If you working on a public chat room (which can contain large number of people), by employing server side strategies simply you'll make your code to a dirty one! Yes, Any user who navigates or refreshes the page can cause a redundant update to all the clients. Best Solution is turning you page to SPA (working with API call or Ajax call) with no page refresh. I believe that any real-time web application should take advantage of modern web technologies. This will solve almost every problem which you suffer (e.g no page refresh, no reRun, no disCoennection & etc ...).
Solutions like using a js timer to fetch latest status for users is not clean or desirable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With