• Asp.Net SignalR 使用记录


    工作上遇到一个推送消息的功能的实现。本着面向百度编程的思想。网上百度了一大堆。主要的实现方式是原生的WebSocket,和SignalR,再次写一个关于Asp.Net SignalR 的demo 

    这里简单的介绍一下Signalr,SignalR 封装了WebSocket、ForeverFrame、ServerSentEvents、LongPolling四种主要的传输协议。兼容性比较好,WebSocket 是有要求的,IIS服务需要系统是Win8或者 Server 2012 以上。下面开始撸代码。

    1.首先建立一个项目。

    2.通过包管理工具,引入SignalR 

    3.引入之后,需要手动添加两个类。

    PushHub 集线器类,Singlarl类的主要操作都由这个类实现。

     1     public class PushHub : Hub
     2     {
     3         /// <summary>
     4         /// 第一次连接
     5         /// </summary>
     6         /// <returns></returns>
     7         public override Task OnConnected()
     8         {
     9             return base.OnConnected();
    10         }
    11 
    12         /// <summary>
    13         /// 断开连接
    14         /// </summary>
    15         /// <param name="stopCalled"></param>
    16         /// <returns></returns>
    17         public override Task OnDisconnected(bool stopCalled)
    18         {
    19             string user = ConnectManager.GetUserName(Context.ConnectionId);
    20             ConnectManager.RemoveUser(user);
    21             Show(string.Format("{0}退出", user));
    22 
    23             return base.OnDisconnected(stopCalled);
    24         }
    25 
    26         /// <summary>
    27         /// 获取当前的用户标识
    28         /// </summary>
    29         /// <returns></returns>
    30         private string GetUserId()
    31         {
    32             return Context.QueryString["userId"];
    33         }
    34 
    35         /// <summary>
    36         /// 发送消息
    37         /// </summary>
    38         /// <param name="content"></param>
    39         /// <param name="receiveUser"></param>
    40         public void Show(string content,string receiveUser="")
    41         {
    42             string user = ConnectManager.GetUserName(Context.ConnectionId);
    43             if (string.IsNullOrEmpty(receiveUser))
    44             {
    45                 Clients.All.show(content);
    46             }
    47             else {
    48                 Clients.Client(ConnectManager.GetUserConnect(receiveUser)).show(string.Format("{0}发消息:{1}",user, content));
    49             }
    50             
    51         }
    52 
    53         /// <summary>
    54         /// 登录操作
    55         /// </summary>
    56         /// <param name="user"></param>
    57         public void Login(string user)
    58         {
    59 
    60             ConnectManager.OnlineInit(user, Context.ConnectionId);
    61             Show(string.Format("{0}:登录成功", user));
    62         }
    63 
    64     }

    4.Startup类

     

        public class Startup
        {
            public void Configuration(IAppBuilder app)
            {
                app.MapSignalR(); //声明注册集线器映射
            }
        }

    5.连接管理类

     1     /// <summary>
     2     /// 连接管理类
     3     /// </summary>
     4     public class ConnectManager
     5     {
     6         /// <summary>
     7         /// 连接记录池
     8         /// </summary>
     9         private readonly static ConcurrentDictionary<string, string> _connectPool = new ConcurrentDictionary<string, string>();
    10 
    11         /// <summary>
    12         /// 添加用户
    13         /// </summary>
    14         /// <param name="userKey"></param>
    15         /// <param name="connection"></param>
    16         public static void AddUser(string userKey, string connection)
    17         {
    18             _connectPool[userKey] = connection;
    19         }
    20 
    21         /// <summary>
    22         /// 删除用户
    23         /// </summary>
    24         /// <param name="userKey"></param>
    25         public static void RemoveUser(string userKey)
    26         {
    27             string connection = null;
    28             _connectPool.TryRemove(userKey, out connection);
    29         }
    30 
    31         /// <summary>
    32         /// 是否存在连接(是否在线)
    33         /// </summary>
    34         /// <param name="receiverId"></param>
    35         /// <returns></returns>
    36         public static bool IsOnline(string receiverId)
    37         {
    38             return _connectPool.Keys.Contains(receiverId);
    39         }
    40 
    41         /// <summary>
    42         /// 推送消息给个人
    43         /// </summary>
    44         /// <param name="receiveId"></param>
    45         /// <param name="msg"></param>
    46         public static void PushSingleMessage(string receiveId, string msg)
    47         {
    48             try
    49             {
    50                 GetHubContext().Clients.Client(_connectPool[receiveId]).show(msg);
    51             }
    52             catch (Exception ex)
    53             {
    54                 var errMsg = ex.Message;
    55             }
    56         }
    57 
    58         /// <summary>
    59         /// 获取推送上下文
    60         /// </summary>
    61         /// <returns></returns>
    62         public static IHubContext GetHubContext()
    63         {
    64             return GlobalHost.ConnectionManager.GetHubContext<PushHub>();
    65         }
    66 
    67         /// <summary>
    68         /// 上线初始化
    69         /// </summary>
    70         /// <param name="userId">用户ID</param>
    71         /// <param name="connectionId">连接ID</param>
    72         public static void OnlineInit(string userId, string connectionId)
    73         {
    74             AddUser(userId, connectionId);
    75         }
    76 
    77         public static string GetUserName(string value)
    78         {
    79             return _connectPool.Where(a => a.Value == value).FirstOrDefault().Key;
    80         }
    81 
    82         public static string GetUserConnect(string userName)
    83         {
    84             return _connectPool[userName];
    85         }
    86     }

    6.前台代码

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <title></title>
    </head>
    <body>
        <div>
            用户名称:<input type="text" id="user" placeholder="输入用户名" class="input" /><input type="button" id="login" value="登录" class="btn btn-sm btn-info" /><br />
            接收人:<input type="text" id="receiveUser" placeholder="接收人(不填默认群发)" class="input" /><br />
            <input type="text" id="content" placeholder="发送内容" class="input" /> &nbsp;&nbsp;<input type="button" value="发送" class="btn btn-sm btn-info" id="send" />
            <div>
                <h4>接收到的信息:</h4>
                <ul id="dataContainer"></ul>
            </div>
        </div>
        <script src="Scripts/jquery-3.3.1.min.js"></script>
        <script src="Scripts/jquery.signalR-2.4.1.min.js"></script>
        <script src="signalr/hubs"></script>  ///这个要注意默认就是这样写,不要问为什么。哈哈
        <script language="javascript">
            $(function () {
                var chat = $.connection.pushHub;
                
                console.log(chat);
                //连接服务端集线器,demoHub为服务端集线器名称,js上首字母须改为小写(系统默认)
                //定义客户端方法,此客户端方法必须与服务端集线器中的方法名称、参数均一致。
                //实际上是服务端调用了前端的js方法(订阅)
                //若多个参数,服务端也需要一致
    
                chat.client.show = function (content) {
                    var html = '<li>' + htmlEncode(content) + "</li>";
                    $("#dataContainer").append(html);
                }
    
                //定义推送
                $.connection.hub.start()
                    .done(function () {
                        $("#login").click(function () {
                            chat.server.login($("#user").val());  //将客户端的content内容发送到服务端
                            $("#user").val("");
                        });
                        $("#send").click(function () {
                            chat.server.show($("#content").val(), $("#receiveUser").val());  //将客户端的content内容发送到服务端
                            $("#content").val("");
                        });
                    });
    
    
            });
            //编码
            function htmlEncode(value) {
                var encodedValue = $('<div />').text(value).html();
                return encodedValue;
            }
        </script>
    </body>
    
    </html>

    这就是所有的demo的代码

    demo代码:https://github.com/chaorending/Demo.SignalR.git

  • 相关阅读:
    C++ 模板函数指针
    MaxScript Object_Oriented_Struct 使用strut 模拟面向对像编程中的 Class
    C# Managed DirectX 学习笔记 一 (基础环境,画三角形,输入的处理)
    C# 代理做为函数参数的时候
    mongoose基本增删改查
    JS中的reduce()详解
    JS中every()和some()的用法
    JS数组遍历方法集合
    第一篇博文
    gb2312 了解
  • 原文地址:https://www.cnblogs.com/DingKing/p/11094560.html
Copyright © 2020-2023  润新知