How to publish messages using the SignalR SqlMessa

2019-04-16 13:19发布

问题:

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!!

回答1:

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
                };
            }
        }
    


标签: signalr