Reputation: 501
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?
Upvotes: 3
Views: 4483
Reputation: 11
//Fetch connection string from config
string connectionString = ConfigurationManager.AppSettings["connectionString"];
// Create the connection
MessagingFactory factory = MessagingFactory.CreateFromConnectionString(connectionString);
//Provide the queue name in the service bus
MessageReceiver receiver = factory.CreateMessageReceiver("queue Name");
BrokeredMessage retrievedMessage = receiver.Receive();
if (retrievedMessage != null)
{
try
{
string output = retrievedMessage.GetBody<string>();
//In the output string you will get the message from the queue.
retrievedMessage.Complete();
}
catch (Exception ex)
{
retrievedMessage.Abandon();
}
}
Upvotes: -1
Reputation: 232
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.
Upvotes: 2
Reputation: 12174
Read "How to Receive Messages from a Queue" in http://www.windowsazure.com/en-us/documentation/articles/service-bus-dotnet-how-to-use-queues/
But, if you have a worker role generating messages and you want to use SignalR, I'd recommend using that worker role as a broadcast hub for SignalR - see Tutorial: Server Broadcast with SignalR 2.0
Upvotes: 2