I have a Windows Service that I'd like to periodically publish some data. I know I can use the .NET HubConnection
object to create a proxy to a SignalR hub and send a message through it but since the web app is hosted on an IIS web farm that can get a bit hacky. The web farm hubs are connected using the SQL Server-based SqlScaleoutConfiguration
backplane. What I'd really like to do some thing like this:
var config = new SqlScaleoutConfiguration(sqlConnString);
GlobalHost.DependencyResolver.UseSqlServer(sqlConnString); //Redundent??
var messageBus = new SqlMessageBus(GlobalHost.DependencyResolver, config);
var message = new Message("DataHub", "RefreshData", payload);
messageBus.Publish(message);
Obviously this doesn't work. Any sample code/documentation on how to interact directly with the SignalR message bus would be greatly appreciated. Thanks!!
Something like this should work with the sql scale out bus although I haven't tested it.
From the SignalR.RabbitMQ project which is a scale out bus using RabbitMQ as the backplane.
Essentially configure the Message Bus in you console project.
Grab a reference to the Hub you want to broadcast to.
Then send your message...
var factory = new ConnectionFactory
{
UserName = "guest",
Password = "guest"
};
var exchangeName = "SignalR.RabbitMQ-Example";
var configuration = new RabbitMqScaleoutConfiguration(factory, exchangeName);
GlobalHost.DependencyResolver.UseRabbitMq(configuration); ;
var hubContext = GlobalHost.ConnectionManager.GetHubContext<Chat>();
Task.Factory.StartNew(
() =>
{
int i = 0;
while (true)
{
hubContext.Clients.All.onConsoleMessage(i++);
System.Console.WriteLine(i);
Thread.Sleep(100);
}
}
);
Mark's answer is correct but >>>>>>>>>>>>>>>>>>>>>
here is what I had to do to make this work for SQL Server scaleout:
Update service:
Create an exact replica of the hub class (or just reference it) that will send the messages to the client. The hub
class will need to contain a placeholder method to allow the messages to flow through it:
public class DataHub : Hub {
// other hub methods here ...
public void RefreshData(SomeAppropriateType messageData)
{
// Placeholder method for tunneling data refreshes through the SQL Server scaleout backplane
}
}
Register the SQL Server database:
var signalrDbConnectionString = ConfigurationManager.ConnectionStrings["signalr"].ConnectionString;
GlobalHost.DependencyResolver.UseSqlServer(signalrDbConnectionString);
routes.MapHubs();
Broadcast the message to all client through the hub proxy class:
var messageData = // instantiate the parameter value of the RefreshData method in the hub class
var hubContext = GlobalHost.ConnectionManager.GetHubContext<DataHub>();
Task.Factory.StartNew(() => hubContext.Clients.All.RefreshData(messageData)).Wait();
Web site:
Same first step of the update service.
Register the SQL Server database just as before but somewhere in the web app global setup.
Write javascript for the appropriate pages along these lines to receive the messages:
function listenForUpdates() {
if (updater === undefined) {
updater = $.connection.dataHub;
}
if (updater !== undefined) {
// Declare a function on the hub so the server can invoke it
updater.client.refreshData = function (value) {
// for debugging: console.log(value);
// update the appropriate page elements with the new data
};
}
}