In our project we are using this on MvcApplication > Application_Start:
new Thread(t => Container.Resolve<IMessageRouter>().StartRouting()).Start();
We are also using DI (Windsor container), router is registered as Transient. Router starting with web-application in parallel thread and working all the time.
Router has SignalR hub connection context and topic listener (topic client wrapper):
public class MessageRouter : IMessageRouter
{
private string _subscriptionName = "Subscription_0";
private IHubConnectionContext ClientContext
{
get { return GlobalHost.ConnectionManager.GetHubContext<MessageHub>().Clients; }
}
private RoleInstance CurrentRoleInstance
{
get // try to get current Azure role instance
{
if (RoleEnvironment.IsAvailable && RoleEnvironment.CurrentRoleInstance != null)
{
return Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.CurrentRoleInstance;
}
return null; // return null if not Azure environment
}
}
private string TopicName
{
get { return ConfigurationHelper.TopicName; }
}
private string TopicConnectionString
{
get { return ConfigurationHelper.TopicConnectionString; }
}
public ITopicListener TopicListener { get; set; }
public void OnMessage(QueueMessage message)
{
ClientContext.Group(message.GetRecipientGroup()).updateProgress(message.GetBody<string>());
}
public void StartRouting()
{
TopicListener.Bind(TopicConnectionString, TopicName, _subscriptionName).StartListening(OnMessage);
}
public MessageRouter()
{
if (CurrentRoleInstance != null) // check Azure environment is exist
{
int instanceIndex = 0; string instanceId = CurrentRoleInstance.Id;
if (!int.TryParse(instanceId.Substring(instanceId.LastIndexOf(".") + 1), out instanceIndex)) // on cloud
{
int.TryParse(instanceId.Substring(instanceId.LastIndexOf("_") + 1), out instanceIndex); // on compute emulator
}
_subscriptionName = String.Format("{0}_{1}", CurrentRoleInstance.Role.Name, instanceIndex);
}
}
}
And it works. Hope this helps.