zoukankan      html  css  js  c++  java
  • SignalR 循序渐进(五)多个Hub服务器下的消息订阅

    SignalR的通讯方式决定了其高性能,但是即便如此,当消息的并发量上来以后,单节点的Hub服务器依然可能无法承载总的消息吞吐量,那么如何对Hub服务器做水平扩展呢?

    从微软官方的文档上看,SignalR是具有消息底板功能的,SignalR核心组件公开了一个IMessageBus的接口,只需要实现该接口,就能实现消息订阅功能。官网提供了3种解决方案:Azure、Redis、SqlServer,nuget平台上有更多的基于消息队列的第三方底板。本篇以Redis为例子展示一下以消息底板模式运作的Hub服务器。

    服务端

    public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                
                GlobalHost.DependencyResolver.UseRedis("192.168.1.66", 6379, string.Empty, "SignalRBus");
                app.Map("/signalr", map =>
                {
                    map.UseCors(CorsOptions.AllowAll);
    
                    var hubConfiguration = new HubConfiguration
                    {
                        EnableJSONP = true
                    };
                    map.RunSignalR(hubConfiguration);
                });
            }
        }

    在启动类中,通过DependencyResolver的扩展方法来注册基于Redis的MessageBus,其中前2个参数是地址和端口,第三个参数为Redis服务器的密码,消息订阅的名称。

    public class ChatHub : Hub
        {
            public void Chat(string msg)
            {
                Clients.All.Display("Receive Msg:" + msg);
            }
        }

    建立一个简单的Hub,只提供一个Chat的方法,内部实现广播。

    static void Main(string[] args)
            {
                using (WebApp.Start<Startup>("http://*:8001/"))
                {
                    Console.WriteLine("Server running at http://localhost:8001/");
                    Console.ReadLine();
                }
            }
    static void Main(string[] args)
            {
                using (WebApp.Start<Startup>("http://*:8002/"))
                {
                    Console.WriteLine("Server running at http://localhost:8002/");
                    Console.ReadLine();
                }
            }

    建立2个启动项,端口号分别为8001和8002,用以启动2个hub的实例。

    客户端

    static void Main(string[] args)
            {
                var hubConn = new HubConnection("http://localhost:8001");
                var proxy = hubConn.CreateHubProxy("ChatHub");
                hubConn.Start().Wait();
                while (true)
                {
                    var guid = Guid.NewGuid().ToString();
                    Console.WriteLine("Send Msg:" + guid);
                    proxy.Invoke("Chat", guid).Wait();
                    Thread.Sleep(2000);
                }
    
            }

    客户端1连接上8001,利用一个循环不断的往服务端发guid。

    static void Main(string[] args)
            {
                var hubConn = new HubConnection("http://localhost:8002");
                var proxy = hubConn.CreateHubProxy("ChatHub");
                proxy.On<string>("Display", (msg) => { Console.WriteLine(msg); });
                hubConn.Start().Wait();
                Console.ReadLine();
            }

    客户端2连接上8002,注册一个Display的方法,用于接收服务端推送的消息。

    运行情况

    image

    图中可知,client1的send msg,被client2接受到了。

  • 相关阅读:
    闪回还原点解析
    先有鸡还是先有蛋的争论
    Android缓存处理
    hdu 1398 Square Coins (母函数)
    JSON具体解释
    【LeetCode】String to Integer (atoi) 解题报告
    【Linux探索之旅】第一部分第四课:磁盘分区,并完毕Ubuntu安装
    MySQL排序:SELECT ORDER BY
    架构师速成7.3-devops为什么非常重要
    升级Linux内核导致vmware无法使用(vmnet模块无法编译)解决方式
  • 原文地址:https://www.cnblogs.com/royding/p/3919134.html
Copyright © 2011-2022 走看看