How can a SignalR client detect logout? - signalr

NB: this question is about SignalR authentication events, not transport events, which I already have covered.
Scenario: I have my SignalR application open in 2 tabs. In one, I log out. In the other, my SignalR connection appears to stay connected, but no response is returned to requests sent through the hub. How can I detect this scenario? I'm already detecting errors, reconnect and disconnect events, but it doesn't seem to correspond to any state change at all. This feels like a relatively common scenario but I can't seem to find any documentation about it.

As far as I can tell, SignalR genuinely doesn't know you've been logged out, so there doesn't seem to be any nice way to do this. I've now implemented a separate http endpoint "IsLoggedIn" that returns true or false, and I poll that via Ajax to work out when the user becomes logged out, but there must be a better way...

Related

Firebase - Automatically sign out user onDisconnect

Since I have noticed that once a user signs in with email and password, on reopening the application the session will not have expired and there is no need for a new authentication, I wish to avoid this.
I want to automatically .signOut() a user when .onDisconnect is triggered. How can I achieve this? I have tried with the following code, but unsuccessfully:
firebase.auth().onDisconnect().signOut();
When you say "onDisconnect", I'm assuming that you mean Realtime Database onDisconnect triggers.
The first thing to know about onDisconnect is that it triggers when the socket connection between Realtime Database and the client app is closed. This could happen for any number of reasons, and it can happen at any time, even if the app seemingly has a good internet connection. So, be careful about what you're trying to do here.
Also, onDisconnect triggers can only affect data in the database directly, and nothing else. So, this limits what you can effectively accomplish. You can't perform any action in the client app in response on an onDisconnect.
Between these two facts, what you're trying to do isn't really possible, and, I don't think it's desirable. You could end up logging out the user just because their train went underground momentarily, or if they simply switched out of the application for some time. This would be massively inconvenient to the user.
If you want to automatically log out the user, I strongly suggesting finding some other way to do this, such as writing some code to remember how long it's been since the user used your app, and forcing the logout on the on the client app based on your preferred logic.
The onDisconnect() is related to the database connection, and has little to do with your authenticated user. As in: onDisconnect() may fire when your user is signed in, simply because the connection to the database drops temporarily.
But more importantly: onDisconnect handlers run server-side, once the server detects that the client has disappeared. When this is because if a dirty disconnect (e.g. the app crashes), there is no way for the client to detect this anymore.
The most likely approach you'll want is to simply sign the user out when they close the app.
Alternative you might want to attach a listener to .info/connected in your client. This is a client-side listener that fires when the client detects that it is connected or disconnected.

how signalR manage concurrent user updates

can anyone tell me please, how SIGNALR manage consurrent user updates. What happened when user click "send" button at a same time. How SIGNALR identify which call is associated to which client.
Each single connection has a unique connectionId which is transmitted across server and clients usually at each call, so there is no issue with that. The server would receive 2 parallel calls but each one will be correctly associated to the right client through the exchanged connectionId. You should check the official documentation here.

Can I prevent other callers from intercepting SignalR Hub messages on the same hub?

The SignalR server hub does not retain a list of groups so I assume that when I send out a broadcast message to a group it is sent to everyone connected to the hub and the clients filter out the message based on their participating groups. If I send a message to a specific group it seems that it is sent down the wire to everyone and can be intercepted by someone not in the specified group who knows how to use a browser debugger. If I want to have a secure broadcast (not even sent over the wire to some clients) I assume I need separate hubs or do I need separate sub domains?
Separate hubs do not sound like a good idea. While you probably can validate users on connect and refuse connections for non-authorized users what if you need a way to create isolated hubs dynamically. If however this functionality is enough for you you can use the Authorize attribute to secure either hubs or hub methods.
For cases where you do need to replicate the same functionality for different groups of users you can use SignalR groups but you need to verify that the user belongs to the group each time he connects. The SignalR documentation contains an example on how to do that verification. Note that everyone can try to connect to your groups and you should validate upon connection and not depend on the fact that you do not call the add method for a certain client.
SignalR only sends to the clients in the group. It's just a design issue that you can't retrieve a list of connections in a group. Groups, as pretty much everything else in SignalR, are subscription based, so the server knows which connections need to receive a message, but it's buried deep in the internals.
I would point you to the relevant server-side code, but don't have time to look it up right now.
It's easy to see in the client-side code though since it's not a lot of code - so you can verify there is no filtering going on there.
Groups also aren't separated per hub.

SignalR just for checking if user is online or not

I would like to ask, if it is a good idea to use SinglR just for knowing if the current user now online or not?
For example I have an small website with log in system, and some where on the side i would like to show the logged in members.
Is this a good idea to use signalr for that?
And if it the case should I then on each page start the connection with hub? (In this case when user navigates on the pages, will be the ReConnected method called on hub, or OnDisconnected and OnConnected)?
I'm just starting with signalr, so curious what ppl think.
You could use SignalR though there might be better methods to do this. So when a user logs in, logs out or becomes inactive - you would have some sort of message being sent from the client to the server that indicates the change in status. You can store that information in a temporary database and whenever a value in the database changes you can use SignalR to relay that information to all the connected clients.
Signalr will get reconnected when the user moves from one page to another page. Whenever a user logs into a website the user security details will be persisted in a cookie assuming you are using Cookiebase authentication. So till the user logs out or session timesout the cookie will be active. So there is no real need for Signalr here.
I have been investigating the same thing. From my research, I would say that you COULD do this, but I'm on the fence of whether it's the best way to go about it. I would expect a LOT of disconnecting, connecting and reconnecting. If you're persisting this data in a database, you should anticipate a lot of database traffic. if you're only on a single server though, you could just persist this in memory.
Something to also note is that the ConnectionId changes with each page refresh. At first, I thought that was dumb because I wanted the connection id to be consistent so i could keep a handle on a user with it. However, if you open a link in a new tab and then close one of them, you have to still keep the other connection in storage. If the id was the same you would remove it on disconnect even though the other tab was open, so your user would incorrectly be marked as offline.
However, the other issue that i'm thinking about is that if you're just browsing around the site in a single tab, you will disconnect for a split second between each page load. So you might run into connection consistency issues with that.
I'd say online presence with signalr is more common to be used for a chat room or game lobby. So I'd say this is possible, but whether it's a good solution -- i'm unsure.

SignalR with unreliable or paused & reconnected connections?

I'm considering updating an existing site to use SignalR. My site polls a third party service for data changes, does some magic on it, and clients poll it once every few minutes to refresh their view with any updates.
SignalR seems like a great way to eliminate the polling from the client, but I want to know how SignalR handles dropped & reconnected connections, especially with regards to mobile web apps which may have been suspended for some time. Will it automatically negotiate and queue up any updates that were missed in the meantime, or does the client need to resynch from scratch in these cases? I looked but couldn't find any docs on this so guidance would be appreciated.
All this is definitely possible since the client keeps track of the last message id it saw. If it happened to miss messages, it'll get those the next time it goes back to the server (asking for all messages since the last one it saw).
By default the server side of SignalR stores messages in memory (and it purges those every few seconds), but you can change it to persist to some persistent store (see IMessageStore) if you're thinking about clients going offline and catching up.
You could even persist messages yourself in your own app logic while SignalR stores stuff in memory. It really depends on the application.
We haven't added any special support for mobile clients, but you can persist the message id in whatever local storage you need to for your mobile client.
Those details aren't very specific but what you want to do is all possible with SignalR.
Read Understanding and Handling Connection Lifetime Events in SignalR, especially these sections:
How to continuously reconnect - required to recover from a disconnected state;
How to notify the user about disconnections - so your app can not only inform the user, but detect state changes (disconnected, reconnecting, reconnected) to refresh your app's state in other ways.
That document was written in 2014 and basically obsoletes many of the wrong or incomplete StackOverflow SignalR-related questions/answers from the 2011-2012 era.

Resources