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接受到了。

  • 相关阅读:
    RecyclerView 数据刷新的几种方式 局部刷新 notify MD
    【图片】批量获取几万张图片
    RV BaseRecyclerViewAdapterHelper 总结 MD
    RecyclerView.ItemDecoration 间隔线
    Kotlin【简介】Android开发 配置 扩展
    Kotlin 特性 语法糖 优势 扩展 高阶 MD
    一个十分简洁实用的MD风格的UI主框架
    折叠伸缩工具栏 CollapsingToolbarLayout
    FloatingActionButton FAB 悬浮按钮
    Glide Picasso Fresco UIL 图片框架 缓存 MD
  • 原文地址:https://www.cnblogs.com/royding/p/3919134.html
Copyright © 2011-2022 走看看