I have a worker role running in windows azure which generates messages. I have an ASP.NET MVC app which has a SignalR hub. I'd like to push messages from the worker role to the SignalR hub which would then push these out to connected clients in real-time. My thoughts would be to use an Azure service bus queue which the ASP.NET MVC app would read from. It all seems straightforward enough of a concept but I'm not sure how to wire up a service bus QueueClient in the MVC app. I can find plenty of samples with ASP.NET MVC putting messages in a queue to be picked up by a worker role service but not the other way round.
Question: Is there are way to do this? Could anyone point me in the direction of some samples etc?
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.