Detect missed messages/missed actions on messages on reconnect - c#

I am using SignalR in my application to send messages to different users in a group.
We have the capability that messages can be added/edited or deleted and the same action is sent to all the users in that group via SignalR hub.
All that is working fine.
The issues is one could miss other people actions (message add/edit/delete) which happened during the time when his connection was lost/ internet disconnected or his laptop/machine was off.
After getting connection back or opening the laptop again that user must receive all those missed messages, missed actions which occurred during the time he was offline.
We are storing all clients (client id) of all users in database.
Can anyone give the pointers how to do that?
One solution can be to poll last message id (which has come to ui) to server check if any new message is there but that won't serve the purpose because message could have been edited/deleted at server from other user.
I have already gone through following links
Can SignalR handle missed messages?
Can a SignalR message loss be detected server side?
How to do guaranteed message delivery with SignalR?
Signalr client to retrieve missed messages on reconnect
https://github.com/JabbR/JabbR/issues/699
but none of them is covering the aspect for the entire history which happened during the time user was offline.
For example if you are disconnected in Skype and comes back say after few hrs it pulls all the history of all actions (message added/edited/deleted) that occurred during that time and update it to end user

Since SignalR doesn't povide any guarantees of message delivery - one should solve this by himself.
There are several approaches:
The first is to use message queues (ex: RabbitMQ).
This is the most efficient way to guarantee that message is delivered to client.
But in your case you'll need to combine message queueng with pub/sub way of communication. That can be tricky.
The second way is described in the answer to one of SO posts, that you referenced: Can SignalR handle missed messages?.
Don't send data over signalr, only notifications; then get the data update from the server.
That is my favourite way of client-server notification/update scheme. And I'd choose it in your case.
One solution can be to poll last message id (which has come to ui) to server check if any new message is there but that won't serve the purpose because message could have been edited/deleted at server from other user.
To overcome this you can poll not the last message, but history of actions made in conversation (add/update/delete message actions) since last updated and apply it on the client side.

Related

Can Microsoft's Service Broker be used for a producer-consumer scenario?

Using SQL Server 2008, ASP.NET, C#/VB/.NET
I have experience using SQL Server, but just starting with Service Broker. I've been looking at Service Broker to help me with the following scenario:
Customers come to our website and submit a request.
This request is sent to a Partner's web service for handling and we get back a request Id (GUID) which both of us can use in tracking the request.
We save info about the request in a Tracking table and wait for status updates from our Partner.
Over the next hours/days/weeks, our Partner sends us status updates on the request via a webhook listener we have running on our end.
For performance reasons, it was recommended this webhook just validate the update and queue it on a "processing queue" for later processing.
We have a processing application which retrieves the status updates from the processing queue and handles the update -- mostly updating the Tracking table and sometimes by requesting files from the Partner. Requesting files may take some time, hence having this processing separate from the webhook receiving the updates. And there is a good possibility we may need several instances of the processing application.
Since we are already using SQL Server, I was hoping to leverage Service Broker to provide the processing queue. Some of the issues I'm struggling with are:
I think we only need 1 processing queue. Most of the SB documentation shows an Initiator and a Target queue.
When the processing app receives an update, I'd like to continue to process more updates for that specific request (conversation groups?). Examples I've seen show receiving a message, sending a response, and then closing the conversation. I'd like to keep the conversation open until we receive a "request complete" update from our Partner.
After receiving an update from the queue, do I need to send a response message? If so, to who? It looks like my Consumer app now has to be also a Producer.
I've read all the warnings about "conversation leaks" and "fire-and-forget" anti-patterns, so I want to follow best practices.
Are there any good examples of using Service Broker for a producer-consumer scenario like this?
If you have any questions or need more information, please let me know. Thanks!
randy

Queue in producer side

In want to use RabbitMQ to send events to a server from a mobile C# app. The user records a lot of events in the whole day (number of products manufactured, consumed water, ...) and they need to be delivered in a server to be processed. I understand that RabbitMQ creates a queue in the server but also, I would like to have a queue en in client side, in the mobile app. It is usual that in some parts of the factory Internet fails, so when the user records any event, it needs to be sent using the RabbitMQ client, but if Internet fails, it should remain in an "internal" queue, waiting to be sent in the next synchronization.
Which is the best approach for this problem? Does have RabbitMQ client library a feature for this purpose?
No RabbitMQ does not provide any such thing , typically for a user case like your it is best to use a local light weight database. You can go for something like SQLite.
Keep the data locally till it is synchronized and once done you may delete it from local.

Checking for disconnect in P2P UDP C#

I'm making an application in which three users get into a session and send each other UDP data (Peer to Peer). How can I detect if one of the users has disconnected from the session?
Because UDP is not connection based, the only way to tell if a user has disconnected is to check if you are no longer receiving responses or messages from them.
One strategy is to have users send 'heartbeat' messages periodically and track if a user has missed the last X number of heartbeats in a row, and at that point assume they are disconnected. These messages don't need to contain any information, just receiving them is what's important.
You should also have users send a "disconnection message" when they disconnect, but do not rely solely on this, as the user may crash or the message may otherwise get lost and never be received.

Ensure / Verify message delivery using MSMQ (C#)

How do you 'verify' that a message sent using MSMQ to a private local queue was actually delivered? I'm especially thinking of a scenario where the listener (a C# service in my case) is not running and therefore delivery can't be successful.
You can only guarantee that it can get to the queue without taking extra steps. To deal with the "not running receiver" scenario, you would need to code the receiver to send a message back to the server when it processes the message. The original sender would be responsible for tracking the sent messages and verifying that the client has recieved them.
That's one of the decisions you should be taking when deciding whether or not to use MSMQ as opposed to a remoting or a web service scenario. For example, we had a project used for notifying all of our retail locations when an emergency occurred (such as a product recall/food safety issue.) We needed to know immediately if the store's listener was running so we chose remoting, and when the sender received an error indicating one of the listeners was not listenting, we would need to pick up the phone and call.
Just something to keep in mind.
Edit - clarification
I was really giving out two options above.
Code the client to send a message back to the sender when it receives a message.
Use another option, such as remoting, where you can detect if the client is running and receives the message.
It's always sent to the queue.
If your service isn't running to receive it, it just sits there, waiting patiently, until someone receives it.
You know it's been sent to the queue because .Send() returns without crashing.
You can probably pull this info out using administrative queues
When you send a message you can specify the AcknowledgeType which will allow you find out (through positive or negative acknowledgement) whether the message reached the queue and/or was received from the queue. Acknowledgements are sent as messages, by MSMQ, to the AdministrativeQueue so make sure you assign that property on the Message object.
You can check the administrative queue for acknowledgements by correlation ID which is ID of the original message.

Programming design architecture for my application

I have the need from an asp.net web site to send out many SMS messages at once, and also poll a POP3 account for an incoming mail, and then SMS that out to many recipients, one at a time.
The way I am thinking of doing this is a windows service that would connect to my sql back-end to see if there are SMS messages to be sent out, like every 10-20 seconds or so. If so, get all the messages in a list, delete them from the table, and then proceed to send them out.
Same way with the pop account.
Any ideas on how to best provide this service without causing blocking in the asp.net web page when it is kicked off (e.g. messages added to sql server)?
Platform is windows server 2003 R2, sql 2008 standard, asp.net 3.5 SP1.
Thanks for your advice.
We have implemented similar scenarios using SQL Server service broker's Queueing mechanism. The idea is that every inserted SMS record is caught by a trigger which inserts a message containing the SmsID into the service broker Queue.
You then need a stored procedure which receives messages from the Queue. If there are no messages, your procedure will run until the next entry is inserted. That's OK, since it does not take up resources to listen to the Queue.
Next you'll need a Windows service who continuously (recursively) calls the STP, assembles the SMS and sends it.
The Advantage of the Service Broker Queue over a flag in a table is thread safety. This way you could have as many instances of your Service as you want w/o having to worry too much about concurrency issues.
You can find a nice Service Broker tutoial here: http://www.developer.com/db/article.php/3640771
Instead of using an Sql Server for the queuing you could use MSMQ (Microsoft Message Queuing) for this.
MSMQ is quite easy to set up and once it is up and running it is more scalable than Sql Server.
So what you could do was to setup a new queue in MSMQ that would receive the messages you wanted to send. The message would normally be some sort of Message object that describe the message, the sender and the recipient.
Then you would either setup a service that would poll the queue at a regular interval or you could setup MSMQ to start a class of your choice each time a new Message was sent to the queue.
If you need a log of the messages you could have the service / sender object write to a log in sql server when the message was sent.

Categories

Resources