Your question almost describes the solution - buffer the notifications fro 500ms then send an array of all of them.
You could do that by pushing the notification in a queue or list and and use a timer to send the notifications every 500ms.
A far better solution though would be to use Reactive Extensions and the Observable.Buffer(Timespan) method, thus avoiding queues and timers.
Subject<string> _subject;
.....
public void InitSubject()
{
_subject=new Subject<string>();
_subject.Buffer(Timespan.FromMilliseconds(500))
.Subscribe(notifications=>SendBatch(notifications));
}
....
public void SendBatch(IList<string> notifications)
{
//Get hold of the SignalR context and send the notifications here
}
public void QueueNotification(string notification)
{
_subject.OnNext(notification);
}
Buffer also allows you to batch a specific number of notifications, or use both a timespan and item limit to send a batch whenever one of the limits is reached.
Your code should call QueueNotification
instead of sending the notification directly. Reactive Extensions also provide LINQ extensions, so you could apply filtering with the Where()
method, eg to use different delays for different user groups, bypass buffering completely, or use any other combination.
You should note that since a Hub is transient, you can't put your subject inside the hub, although you can put QueueNotification
in there, provided you provide a reference to the subject somewhere, eg by using Dependency injection to initialize the hub