Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Guaranteed delivery in SignalR

Tags:

signalr

I'm evaluating SignalR for a medium-load web application.

We're expecting ~500 msgs / sec, which shouldn't be a problem with SignalR.

However, we're worried about the reliability of this solution. Our environment has a problematic network, and it's not rare for a client to lose its network connection for ~30 secs. Is there any mechanism to ensure that once the client reconnects, it gets all the messages that were sent during its offline time?

Thanks!

like image 977
ml123 Avatar asked Dec 26 '12 16:12

ml123


2 Answers

One fairly easy way to handle this would be to assign each message an ID that increments with each message. The client would need to keep track of the latest message that he'd received, and upon reconnection would just send that message ID to the server; and the server would then need to send all the missed messages down to the client. Should be reasonably simple to implement.

EDIT: I don't think you'd have to maintain any real state on the server proper - I think almost all of it could get pushed out to your datastore or to your client. The client would send up the ID or timestamp of the last message that it had received:

$.connection.myHub.server.updateMe(lastMessageId);

You'd want some sort of backing datastore - so when the server receives the updateMe() message, it would do a query on the database and pull out all the rows with an ID greater than the one it just received. It would return those to the client as part of the return value of its UpdateMe() method. And then it would try to deliver any new messages that come along the same way it normally would, by calling methods on the client.

As for statelessness being a goal of SignalR: I can't comment on that, beyond observing that I can't imagine any reasonably complex real-world application that wouldn't need to do have some sort of backing datastore, whether it's on SignalR or some other framework (WCF, XSockets, etc.) makes little difference.

like image 111
Ken Smith Avatar answered Feb 02 '23 01:02

Ken Smith


You could ofcourse use some kind of queing framework but to achive this with minimum effort you can do it like this...

Serverside: http://pastebin.com/tuicQYGq Clientside: http://pastebin.com/a8EbusuG

I am using XSockets.NET that is a realtime communication platform (since 2009) and the controllers in XSockets.NET have state so this is easy to do.

EDIT: Ohh... to test this use two browsers for example chrome and safari, then disconnect one browser... send some messages from the other then reconnect to see the messages appear. You have to use two different browsers on localhost since xsockets will give each browser a unique storage-id.

EDIT: Added Func to the queue so that you can target specific clients even if they are offline. Now only clients matching conditions will get messages if you want to.

Regards Uffe

like image 29
Uffe Avatar answered Feb 02 '23 01:02

Uffe