工作上遇到一个推送消息的功能的实现。本着面向百度编程的思想。网上百度了一大堆。主要的实现方式是原生的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类

  1. public class Startup
  2. {
  3. public void Configuration(IAppBuilder app)
  4. {
  5. app.MapSignalR(); //声明注册集线器映射
  6. }
  7. }

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.前台代码

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8" />
  5. <title></title>
  6. </head>
  7. <body>
  8. <div>
  9. 用户名称:<input type="text" id="user" placeholder="输入用户名" class="input" /><input type="button" id="login" value="登录" class="btn btn-sm btn-info" /><br />
  10. 接收人:<input type="text" id="receiveUser" placeholder="接收人(不填默认群发)" class="input" /><br />
  11. <input type="text" id="content" placeholder="发送内容" class="input" /> &nbsp;&nbsp;<input type="button" value="发送" class="btn btn-sm btn-info" id="send" />
  12. <div>
  13. <h4>接收到的信息:</h4>
  14. <ul id="dataContainer"></ul>
  15. </div>
  16. </div>
  17. <script src="Scripts/jquery-3.3.1.min.js"></script>
  18. <script src="Scripts/jquery.signalR-2.4.1.min.js"></script>
  19. <script src="signalr/hubs"></script> ///这个要注意默认就是这样写,不要问为什么。哈哈
  20. <script language="javascript">
  21. $(function () {
  22. var chat = $.connection.pushHub;
  23.  
  24. console.log(chat);
  25. //连接服务端集线器,demoHub为服务端集线器名称,js上首字母须改为小写(系统默认)
  26. //定义客户端方法,此客户端方法必须与服务端集线器中的方法名称、参数均一致。
  27. //实际上是服务端调用了前端的js方法(订阅)
  28. //若多个参数,服务端也需要一致
  29.  
  30. chat.client.show = function (content) {
  31. var html = '<li>' + htmlEncode(content) + "</li>";
  32. $("#dataContainer").append(html);
  33. }
  34.  
  35. //定义推送
  36. $.connection.hub.start()
  37. .done(function () {
  38. $("#login").click(function () {
  39. chat.server.login($("#user").val()); //将客户端的content内容发送到服务端
  40. $("#user").val("");
  41. });
  42. $("#send").click(function () {
  43. chat.server.show($("#content").val(), $("#receiveUser").val()); //将客户端的content内容发送到服务端
  44. $("#content").val("");
  45. });
  46. });
  47.  
  48. });
  49. //编码
  50. function htmlEncode(value) {
  51. var encodedValue = $('<div />').text(value).html();
  52. return encodedValue;
  53. }
  54. </script>
  55. </body>
  56.  
  57. </html>

这就是所有的demo的代码

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

Asp.Net SignalR 使用记录的更多相关文章

  1. Asp.Net SignalR 使用记录 技术回炉重造-总纲 动态类型dynamic转换为特定类型T的方案 通过对象方法获取委托_C#反射获取委托_ .net core入门-跨域访问配置

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

  2. [Asp.net 开发系列之SignalR篇]专题一:Asp.net SignalR快速入门

    一.前言 之前半年时间感觉自己有点浮躁,导致停顿了半年多的时间没有更新博客,今天重新开始记录博文,希望自己可以找回初心,继续沉淀.由于最近做的项目中用到SignalR技术,所以打算总结下Asp.net ...

  3. ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(六) 之 Layim源码改造右键菜单--好友、组管理功能的实现。

    前言 上一篇中讲解了加好友的流程,本篇将介绍好友管理,群组管理的右键菜单功能.当然由于菜单项目太多,都实现也得花费时间.只讲解一下我是如何从不知道怎么实现右键菜单到会自定义菜单的一个过程.另外呢,针对 ...

  4. 第一章ASP.NET SignalR简介

    第一章ASP.NET SignalR简介 1.1概述: ASP.NET SignalR是微软新开发的类库,为的是帮助ASP.NET开发人员很方便地开发实时网络功能. SignalR允许服务器端和客户端 ...

  5. ASP.NET SignalR 2.0入门指南

    ASP.NET SignalR 2.0入门指南 介绍SignalR ASP.NET SignalR 是一个为 ASP.NET 开发人员的库,简化了将实时 web 功能添加到应用程序的过程.实时Web功 ...

  6. 使用ASP.NET SignalR实现一个简单的聊天室

    前言 距离我写上一篇博客已经又过了一年半载了,时间过得很快,一眨眼,就把人变得沧桑了许多.青春是短暂的,知识是无限的.要用短暂的青春,去学无穷无尽的知识,及时当勉励,岁月不待人.今天写个随笔小结记录一 ...

  7. WinForm中 Asp.Net Signalr消息推送测试实例

    p{ text-align:center; } blockquote > p > span{ text-align:center; font-size: 18px; color: #ff0 ...

  8. 连表查询都用Left Join吧 以Windows服务方式运行.NET Core程序 HTTP和HTTPS的区别 ASP.NET SignalR介绍 asp.net—WebApi跨域 asp.net—自定义轻量级ORM C#之23中设计模式

    连表查询都用Left Join吧   最近看同事的代码,SQL连表查询的时候很多时候用的是Inner Join,而我觉得对我们的业务而言,99.9%都应该使用Left Join(还有0.1%我不知道在 ...

  9. ASP.NET SignalR入门

    前言 之前在培训ASP.NET WebAPI的时候有提过SignalR这个技术,但当时只是讲了是用来做什么的,并没有多说.因为自己也是画图找资料的时候见到的.后来当一直关注的前端大神贤心发布LayIM ...

随机推荐

  1. DevExpress的TextEdit控件没法调整高度解决

    场景 Winform控件-DevExpress18下载安装注册以及在VS中使用: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/1 ...

  2. dependencies和devDependencies区别

    vue-cli3.x项目的package.json中,有两种依赖: dependencies:项目依赖.在编码阶段和呈现页面阶段都需要的,也就是说,项目依赖即在开发环境中,又在生产环境中.如js框架v ...

  3. 滑动门出现的背景---实例微信导航栏(a盒子里面包span盒子,文字写在span里)

    需求: 制作网页时,为了美观,常常需要为网页元素设置特殊形状的背景,比如微信导航栏,有凸起和凹下去的感觉,其中最大的问题是字数不同,如何做? 解决: 用一个a包含span来制作,字数放在span里面. ...

  4. HTML中引用CSS的几种方法

    HTML中引用CSS的方法主要有 行内样式 内嵌式 链接式 导入样式 行内样式 指写在标签里的Style元素的值 <p style="color: #FF0000;"> ...

  5. es6 最新函数封装(简易版)

    map封装: Array.prototype.map=function(fn){ var arr=this; var newArr=[] for(var i=0;i<arr.length;i++ ...

  6. 顺F速运国际版,你的密码漏点了

    - 加密情况分析 对APP的分析过程,当然首先是安装,使用,抓包啦. 同样地,登录,抓包看看. 使用账号密码登录. - 壳呢? 虽然直接解密了顺F国际版的加密数据,但还是有必要看看它的APK. 经过分 ...

  7. [b0026] python 归纳 (十一)_线程_threading.Thread

    总结: 默认父线程跑完,子线程并不会马上退出,不像 thread.start_threadXXXX 父线程跑完了,并没有退出,一直在那里 线程启动速度很快,不占多少开销,不到1毫 秒 代码: # -* ...

  8. linux基础学习(一)常用命令:date、pwd、cd、cal、who、wc等等

    目录 @(基础命令) Tab键是linux系统中最重要的键之一了,它的功能是命令自动补全== [root@localhost ~]#date 1.用于显示当前的日期和时间 2/用于显示当前的日历 [r ...

  9. C学习笔记(8)--- 文件读写

    1.C 文件读写: 一个文件,无论它是文本文件还是二进制文件,都是代表了一系列的字节.C 语言不仅提供了访问顶层的函数,也提供了底层(OS)调用来处理存储设备上的文件. a.打开文件: FILE *f ...

  10. TCP协议如何保证可靠传输

    TCP协议如何保证可靠传输 概述: TCP协议保证数据传输可靠性的方式主要有: (校 序 重 流 拥) 校验和: 发送的数据包的二进制相加然后取反,目的是检测数据在传输过程中的任何变化.如果收到段的检 ...