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.首先建立一个项目。
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" /> <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