This article covers the basic setup and Unity integration of
using SignalR in a MVC project.
1.
Basic Setup
There are three steps in using SignalR in MVC:
·
Adding SignalR library;
·
creating OWIN startup classes to setup SignalR
route;
·
writing server side and client side code.
First you need to use NuGet to install
Microsoft.AspNet.SignalR package.
install-package Microsoft.AspNet.SignalR
This will install both server side packages and client side
JavaScript libraries into your MVC project.
using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(MyNamespace.SignalRStartup))]
namespace MyNamespace
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
// Any connection or hub wire up and configuration should go here
app.MapSignalR();
}
}
}
In the server side, you need to create a Hub subclass in
your controller folder. A sample is
using System;
using System.Web;
using Microsoft.AspNet.SignalR;
namespace SignalRChat
{
public class ChatHub : Hub
{
public void Send(string message)
{
// Call the broadcastMessage method to update clients.
Clients.Others.broadcastMessage(message);
}
}
}
In your Web application, the View file should include "~/Scripts/jquery-{version}.js",,"~/Scripts/jquery.signalR-{version}.js" and
"~/signalr/hubs".
In the client side, you need to call the server side method
as well as define a method to be called by Server side method. The code may look like the following:
var chat = $.connection.chatHub;
$.connection.hub.start().done(function () {
$('#sendmessage').click(function () {
chat.server.send('Hello World');
});
});
chat.client.broadcastMessage = function (message) {
alert(message);
};
The JavaScript code use camel-cased version of the server
method name. The generated signalR proxy
automatically convert a method name to a correct one. In the server side, there
is no method name conversion. A server calls the camel-cased JavaScript client
method.
2.
Working with Unity IoC container
After using NuGet to install Unity and Asp.Net SingalR
packages, one needs to perform the following steps to resolve types for SignalR
methods using a Unity container. There are two options to use Unity as
dependency resolve in SignalR: one is to replace the whole SignalR dependency
resolver; the other option is to only replace the IHubActivator component of
the SignalR dependency resolve. The first one is document in
http://www.asp.net/signalr/overview/signalr-20/extensibility/dependency-injection.
It needs to implement two methods (GetService and GetServices) of SingalR IDependcyResolver
interface. The second option only needs to implement one method of SingalR IHubActivator
interface.
First, create a class implementing IHubActivator interface. In
the class, use a Unity container in the IHub Create(HubDescriptor descriptor)
method.
using System;
using Microsoft.AspNet.SignalR.Hubs;
using Microsoft.Practices.Unity;
namespace SignalRHostWithUnity.Unity
{
public class UnityHubActivator : IHubActivator
{
private readonly IUnityContainer container;
public UnityHubActivator(IUnityContainer container)
{
this.container = container;
}
public IHub Create(HubDescriptor descriptor)
{
if (descriptor == null)
{
throw new ArgumentNullException("descriptor");
}
if (descriptor.HubType == null)
{
return null;
}
object hub = this.container.Resolve(descriptor.HubType) ?? Activator.CreateInstance(descriptor.HubType);
return hub as IHub;
}
}
}
Next, set SingalR Hub resolver in the Unity configuration
file. There is no need to register
IHubActivator in Unity as described in the above reference because this
interface is only used by SignalR and should be registered only in the SignalR
dependency resolver.
var container = new UnityContainer();
GlobalHost.DependencyResolver.Register(
typeof(IHubActivator),
() => new UnityHubActivator(container));
Finally, register every application Hub class in the Unity
configuration file.
container.RegisterType<MyHub, MyHub>(new TransientLifetimeManager());
Together, the Unity configuration file looks like below:
var container = new UnityContainer();
container.RegisterType<MyHub, MyHub>(new TransientLifetimeManager());
… // register other types
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
GlobalHost.DependencyResolver.Register(
typeof(IHubActivator),
() => new UnityHubActivator(container));