Skip to content

Instantly share code, notes, and snippets.

@ScottGuymer
Last active October 24, 2015 13:13
Show Gist options
  • Save ScottGuymer/bbc2c5da328be09e2916 to your computer and use it in GitHub Desktop.
Save ScottGuymer/bbc2c5da328be09e2916 to your computer and use it in GitHub Desktop.
SignalR notifications framework example.
using StratComm.Notification.Hubs.Clients;
public class ExampleHub : SubscriptionHub<IHubClient>
{
}
public interface IFileHubClient
{
void Complete();
void Locked();
void Unlocked();
void Progress(double percentageComplete);
}
using System;
public interface ISignalRNotification<T>
{
T HubClient { get; set; }
ISignalRNotification<T> Of(Action<T> clientMethod);
}
public interface ISignalRNotifier<T>
{
ISignalRProgressNotification<T> NotifyGroupOfProgress(string groupId);
ISignalRNotification<T> NotifyGroup(string groupId);
ISignalRNotification<T> NotifyUser(string userId);
}
using System;
public interface ISignalRProgressNotification<T> : ISignalRNotification<T>
{
ISignalRProgressNotification<T> OnClientWith(Action<T, double> clientProgressMethod);
ISignalRProgressNotification<T> SetProgress(double percentComplete);
}
using System;
public class SignalRNotification<T> : ISignalRProgressNotification<T>
{
private Action<T, double> progressAction;
public SignalRNotification(T hubClient)
{
this.HubClient = hubClient;
}
public T HubClient { get; set; }
private double? LastReported { get; set; }
public ISignalRNotification<T> Of(Action<T> clientMethod)
{
clientMethod(this.HubClient);
return this;
}
public ISignalRProgressNotification<T> OnClientWith(Action<T, double> clientProgressMethod)
{
this.progressAction = clientProgressMethod;
return this;
}
public ISignalRProgressNotification<T> SetProgress(double percentComplete)
{
if (this.progressAction == null)
{
throw new ApplicationException("Client progress method is not set");
}
var difference = percentComplete - this.LastReported;
// We only want to report in 1 percent increments
if (!this.LastReported.HasValue || difference >= 0.01)
{
this.progressAction(this.HubClient, percentComplete);
this.LastReported = percentComplete;
}
return this;
}
}
using Microsoft.AspNet.SignalR;
public class SignalRNotifier<T> : ISignalRNotifier<T>
{
private readonly IHubContext<T> notifyHub;
public SignalRNotifier(IHubContext<T> notifyHub)
{
this.notifyHub = notifyHub;
}
public ISignalRProgressNotification<T> NotifyGroupOfProgress(string groupId)
{
var notification = new SignalRNotification<T>(this.notifyHub.Clients.Group(groupId));
return notification;
}
public ISignalRNotification<T> NotifyGroup(string groupId)
{
return new SignalRNotification<T>(this.notifyHub.Clients.Group(groupId));
}
public ISignalRNotification<T> NotifyUser(string userId)
{
return new SignalRNotification<T>(this.notifyHub.Clients.User(userId));
}
}
using Microsoft.AspNet.SignalR;
public abstract class SubscriptionHub<T> : Hub<T>
where T : class
{
public void Subscribe(string groupId)
{
this.Groups.Add(this.Context.ConnectionId, groupId);
}
public void Unsubscribe(string groupId)
{
this.Groups.Remove(this.Context.ConnectionId, groupId);
}
}
// hubs
container.Register(Classes.FromAssemblyInThisApplication()
.BasedOn<IHub>()
.LifestyleTransient());
container.Register(Classes.FromAssemblyInThisApplication()
.BasedOn(typeof(Hub<>))
.LifestyleTransient());
container.Register(
Component
.For<IHubContext<IFileHubClient>>()
.UsingFactoryMethod(() => GlobalHost.ConnectionManager.GetHubContext<FileHub, IFileHubClient>())
.LifestyleTransient());
container.Register(
Component
.For<IHubContext<INotificationClient>>()
.UsingFactoryMethod(() => GlobalHost.ConnectionManager.GetHubContext<NotificationHub, INotificationClient>())
.LifestyleTransient());
// notifications
container.Register(
Component
.For(typeof(ISignalRNotifier<>))
.ImplementedBy(typeof(SignalRNotifier<>))
.LifestyeHybridPerWebRequestOrJob());
container.Register(
Component
.For<IUserStatusService>()
.ImplementedBy<UserStatusService>()
.LifestyleSingleton());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment