SignalR 集线器

Posted zengtianli

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SignalR 集线器相关的知识,希望对你有一定的参考价值。

//1.启动
public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.Map("/signalr", map =>
            {
                //跨域
                map.UseCors(CorsOptions.AllowAll);
                //集线器
                var hubConfiguration = new HubConfiguration
                {
                    EnableJSONP = true
                };
                map.RunSignalR(hubConfiguration);
            });

        }
    }
//2.简单集线器
/// <summary>
    /// 集线器
    /// </summary>
    public class CharHub : BaseHub
    {
        //log类声明为局部静态是为性能考虑
        private static readonly LogHelper LogHelper = new LogHelper();
        protected static IList<UserModel> UserModelList = new List<UserModel>();
        /// <summary>
        /// 初始化上线
        /// </summary>
        /// <param name="userid">用户id</param>
        public void Online(string userid)
        {
            string connId = Context.ConnectionId;
            LogHelper.Debug((UserModelList.Count + 1) + " 用户【" + userid + "】上线了,ConerctionId:" + connId);
            if (string.IsNullOrEmpty(userid)) { return; }
            var model = UserModelList.SingleOrDefault(q => q.UserConnerctionId == connId);
            if (model == null)
            {
                userid = Uri.EscapeDataString(userid);
                UserModelList.Add(new UserModel() { UserConnerctionId = connId, UserId = userid });
            }
        }

        /// <summary>
        /// 用户发送消息转发处理
        /// </summary>
        /// <param name="userid"></param>
        /// <param name="msg"></param>
        public void ServiceSendMsg(string userid, string msg)
        {
            if (string.IsNullOrEmpty(userid)) { return; }
            userid = Uri.EscapeDataString(userid);
            var list = UserModelList.Where(q => q.UserId == userid).ToList();
            foreach (var model in list)
            {
                if (model != null)
                {
                    //对于这里属于发送给Client的消息
                    //对于前端作为接收方法
                    Clients.Client(model.UserConnerctionId).ReceiveMsg(msg);

                }
            }
            LogHelper.Debug(string.Format("服务推送消息给【{0}】,消息内容为{1}", userid, msg));
            //发送给所有用户
            //Clients.All.ReceiveMsg(msg);
            //发送给组
            //Clients.Group("1").ReceiveMsg(msg);
        }
        public void ServiceSendMsg(string msg)
        {
            //发送给所有用户
            Clients.All.ReceiveMsg(msg);
        }
        /// <summary>
        /// 下线
        /// </summary>
        /// <param name="stopCalled"></param>
        /// <returns></returns>
        public override Task OnDisconnected(bool stopCalled)
        {
            string connId = Context.ConnectionId;
            var model = UserModelList.SingleOrDefault(q => q.UserConnerctionId == connId);
            if (model != null)
            {
                UserModelList.Remove(model);
                LogHelper.Debug("用户【" + Uri.UnescapeDataString(model.UserId) + "】下线了,ConerctionId:" + connId);
            }
            return base.OnDisconnected(stopCalled);
        }

        /// <summary>
        /// 上线
        /// </summary>
        /// <returns></returns>
        public override Task OnConnected()
        {
            return base.OnConnected();
        }

        public override Task OnReconnected()
        {
            return base.OnReconnected();
        }

  //3.客户端

public class ClinetHubTask
    {
        private static readonly string Port = ConfigurationManager.AppSettings["SignalRPort"];
        private static readonly string SignalRServerUrl = string.Format("http://localhost:{0}/signalr", Port);
        /// <summary>
        /// 消息实体推送
        /// </summary>
        /// <param name="userid"></param>
        /// <param name="msg"></param>
        public static void PushMsgForMsgObject(string userid, object msg)
        {
            //序列化
            var jsonMsg = msg as string ?? JsonConvert.SerializeObject(msg);
            PushMsg(userid, jsonMsg);
        }
        /// <summary>
        /// 推送指定客户
        /// </summary>
        /// <param name="userid"></param>
        /// <param name="msg"></param>
        public static void PushMsg(string userid, string msg)
        {
            var url = SignalRServerUrl;
            var conn = new HubConnection(url, true);
            var proxy = conn.CreateHubProxy("CharHub");

            conn.Start();
            conn.StateChanged += new Action<StateChange>(tgt =>
            {
                if (((StateChange)tgt).NewState == Microsoft.AspNet.SignalR.Client.ConnectionState.Connected)
                {
                    //客户端调用服务端的 第一个方法,后面传入参数         
                    proxy.Invoke("ServiceSendMsg", userid, msg);
                }
            });
            conn.Stop();
            conn.Dispose();
        }

        /// <summary>
        ///推送所有用户
        /// </summary>
        /// <param name="msg"></param>
        public static void PushAllMsg(string msg)
        {
            var url = SignalRServerUrl;
            var conn = new HubConnection(url, true);
            var proxy = conn.CreateHubProxy("CharHub");

            conn.Start();
            conn.StateChanged += new Action<StateChange>(tgt =>
            {
                if (((StateChange)tgt).NewState == Microsoft.AspNet.SignalR.Client.ConnectionState.Connected)
                {
                    //客户端调用服务端的 第一个方法,后面传入参数         
                    proxy.Invoke("ServiceSendMsg", msg);
                }
            });
            conn.Stop();
            conn.Dispose();
        }
    }

 //4.web

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>简单聊天程序</title>
    <style type="text/css">
        .container {
            background-color: #99CCFF;
            border: thick solid #808080;
            padding: 20px;
            margin: 20px;
        }
    </style>
</head>
<body>
    <div class="container">
        <input type="text" id="message" />
        <input type="button" id="sendmessage" value="Send" />
        <input type="hidden" id="displayname" value="uuuu" />
        <ul id="discussion"></ul>
    </div>
    <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
    <script src="Scripts/jquery.signalR-2.2.3.min.js"></script>
    <script src="http://localhost:8888/signalr/hubs"></script>
    <script type="text/javascript">
        $(function () {
            //日记记录
            $.connection.hub.logging = true;

            //设置hubs的url
            $.connection.hub.url = "http://localhost:8888/signalr";

            // 声明一个代理来引用该集线器。
            var chat = $.connection.charHub;

            // 创建一个方法供服务端调用
            chat.client.ReceiveMsg = function (message) {
                var encodedName = $(<div />).text($(#displayname).val()).html();
                var encodedMsg = $(<div />).text(message).html();
                $(#discussion).append(<li><strong> + encodedName + </strong>:&nbsp;&nbsp; + encodedMsg + </li>);
                message = JSON.parse(message);
                eval(message["FunctionName"] + "()");
            };

            // 启动 connection
            $.connection.hub.start().done(function () {
                //调用服务器端方法
                chat.server.online($(#displayname).val());

                $(#sendmessage).click(function () {
                    //调用服务器端方法
                    chat.server.serviceSendMsg($(#displayname).val(), $(#message).val());
                });
            });
        });
        //标样与量
        function aaaa() {
            //读取后台数据并且填充页面
            console.log("ddddd")
        }
    </script>
    <!--
    总结一下:
    1.先引入jq包,再引入signalR的js包,再引入signalR动态生成的hubs
    2.设置signalR的hubs url地址:$.connection.hub.url =xxx
    3.声明一个代理对象来引用集线器:var chat = $.connection.dntHub;
    4.创建一个客户端方法:chat.client.xxxx=function(){}
    5.启动并调用服务端方法:
        $.connection.hub.start().done(function(){
            chat.server.xxx()
        });
    -->
</body>
</html>

 

 

 

以上是关于SignalR 集线器的主要内容,如果未能解决你的问题,请参考以下文章

SignalR 集线器连接在 Xamarin Forms iOS 中不起作用

如何从 iOS 上的 PhoneGap 应用程序连接到 SignalR 集线器?

SignalR 控制台应用程序示例

SignalR:为啥选择集线器与持久连接?

ASP.NET Core SignalR:集线器Hubs

SignalR 集线器