欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Asp.Net SignalR 使用记录

程序员文章站 2022-05-03 22:30:50
工作上遇到一个推送消息的功能的实现。本着面向百度编程的思想。网上百度了一大堆。主要的实现方式是原生的WebSocket,和SignalR。 这里简单的介绍一下Signalr,SignalR 封装了WebSocket、ForeverFrame、ServerSentEvents、LongPolling四 ......

工作上遇到一个推送消息的功能的实现。本着面向百度编程的思想。网上百度了一大堆。主要的实现方式是原生的websocket,和signalr。

这里简单的介绍一下signalr,signalr 封装了websocket、foreverframe、serversentevents、longpolling四种主要的传输协议。兼容性比较好,websocket 是有要求的,iis服务需要系统是win8或者 server 2012 以上。下面开始撸代码。

1.首先建立一个项目。

Asp.Net SignalR 使用记录

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

Asp.Net 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类

 Asp.Net SignalR 使用记录

 

    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);
            //连接服务端集线器,de*b为服务端集线器名称,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