3

What I need to do :

I've been asked to add a feature to one of our application that would allow a supervisor to send a message to all or one of the users currently using the application.

The application is a winform application using c# and ef6 with a mysql database and is using a RabbitMQ server for different purposes.

My question :

How can I get or maintain a list of users who are currently using the application?

Solution 1:

Log in a database who is currently using the application.

We have done that in the past for another application, but it was unreliable because if the user kill the application or lose a connection to the database, it won't write to the database if he log off.

Solution 2:

I could use the RabbitMQ server. Every user would send a "presence" message every x seconds to tell the other users they are still logged in. Everytime the application would receive such a message, it would add the user to a list or just update the list if the user is already in the list.. If a user would not send a "presence" message after x seconds, he would be considered as logged off.

Am I overthinking this? Is there a better way to implement such a thing?

Edit : i'm trying to avoid having a central server that would maintain the list of user.

asked Jul 21, 2016 at 17:44
2
  • Do I understand it right the Windows Forms application is connected to a server and communicates with it, when you use it? Commented Jul 21, 2016 at 18:07
  • We're using the RabbitMQ server to send jobs to other applications, notifications to mobile applications, etc. So far, the application is not receiving anything from the RabbitMQ server, so it is only connected when it has to send something. Anyway, I don't think the API provide a way to get the list of connection to a queue or anything. Commented Jul 21, 2016 at 18:12

4 Answers 4

1

The most feasible solution is some variation of Websockets. Luckily, C# supports it. When a user starts the application, a connection between him and a server is created indicating the application runs. When the application is terminated (properly or killed), the process ends and so does the connection.

There's a catch, though. Your current architecture, from what I understand, does not support it. You will need a server which can process WebSocket connections to serve as a listener and manager of your active users. Through this server you may dispatch events to them (WebSockets are bidirectional, meaning it supports both client->server and server->client communication).

Update: I'm no C# programmer, but there seems to be also SignalR. You may want to check that as well.

answered Jul 21, 2016 at 18:19
7
  • Yeah, I'm trying to avoid a server based solution. Commented Jul 21, 2016 at 18:26
  • 1
    Why @KiNeTiC? It's really the way to go about this. You're looking for asynchronous communication between clients. That's exactly what client-server-client architecture is for. Even if you're polling the database, that's essentially what you have, only poorly implemented. Do you really want to be the guy being cursed because you're hitting the database 20 times a minute for no reason? Commented Jul 21, 2016 at 18:31
  • Btw, IIRC, SignalR is built on top of Websockets to abstract some of the lower levels details away. Commented Jul 21, 2016 at 18:32
  • 1
    @KiNeTiC It is much more elegant (and much more effective) than storing the data about users in the database (you even already mentioned the problem when a user kills the process) or pinging the RabbitMQ server several times a minute (I am not sure how this solves your craving for push notifications either). The best part is, working with WebSockets is not that complicated, fairly easy to setup. Take a look at the protocol, you might be surprised. :) Commented Jul 21, 2016 at 18:44
  • My craving for push notifications? I'll look into SignalR more deeply. Commented Jul 21, 2016 at 18:54
0

Some of your architectural constraints are:

  • Client workstation machines running native Win application
  • No centralized server
  • Centralized database
  • Outbound MQ interface

The only feasible solution that scales that I can see under these constraints are:

  • Maintain a user session table
  • User session table is regularly updated every [interval] with a timestamp to prove the application is still alive, timestamp is nulled out when properly shut down
  • New feature implemented for Supervisor role in the application
  • Feature screen allows for a message to be published and sent to everyone with a current and valid timestamp in the database
  • ?? No idea what kind of message ?? On screen display? Email? Assuming email, supervisors application instance will either directly push to an SMTP relay or to a queue in MQ that is picked up by a mail server.
answered Jul 21, 2016 at 19:26
1
  • Kind of message : on screen display. But this is not where my problem is. I'm only struggling to find a correct way to maintain a active users list in a serverless architecture. I know can convince my boss to go the server way if needed. Commented Jul 21, 2016 at 19:38
0

Use the DbConnection's StateChange event. AddToTable would add the user's login to a table on the server, removeFromTable would delete it.

 private void StateChange(object sender, StateChangeEventArgs e)
 {
 var connectionState = e.CurrentState;
 switch (connectionState)
 {
 case ConnectionState.Open:
 addToTable @user
 break;
 default:
 removeFromTable @user
 break;
 }
 }
answered Aug 10, 2016 at 18:50
0

There is decentralized way to do this if not actively hitting a server is really that important.

You own the client so you can make it peer to peer. Peer to peer is a fancy way to say 'it's both a client and a server'

So now when a client connects it needs some way to learn who the other clients are. Well crap were back to needing a server. But this list is just about learning who might be out there. You log in. You report an ip and port you'll be listening on if anyone wants to check your status.

But but security!

If you don't trust the client to actually respond when asked to you can test for a response when they log in. Many IRCd servers do exactly this to ensure you are on the ip you claim to be on.

It's a fair bit of fuss but it avoids polling over the network. You only ask who's on when you care who's on.

answered Aug 10, 2016 at 19:11

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.