欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

利用SignalR实现实时推送信息功能 有大用 有大大用

利用SignalR实现实时推送信息功能

           
何向宇
0.666                    字数 1,101阅读 13,337                

一段时间没写简书了,感谢这段时间以来不断收到大家的支持和喜欢,让我感觉到自己写的一些东西还是能为大家提供一些小小的帮助的,是你们给了我动力继续写文章和教程,在此表示再次的感谢。下面将给大家分享的是有关于SignalR的技术的一种应用。

一、什么是SignalR?
SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信。
什么是实时通讯?
就是当所连接的客户端变得可用时服务器代码可以立即向其推送内容,而不是让服务器等待客户端请求新的数据。当WebSockets可用时(即浏览器支持Html5,SignalR使用WebSockets,当不支持时SignalR将使用其它技术来保证达到相同效果。

二、主要用途:
它出现的主要目的是实现服务器主动推送(Push)消息到客户端页面,这样客户端就不必重新发送请求或使用轮询技术来获取消息。
可以用在聊天室、看板、单点通讯、多点通讯,甚至可以结合其他技术用来做视频聊天。当然也有其他用途。

三、实现机制:
SignalR 的实现机制与 .NET WCF是相似的,都是使用远程代理来实现。在具体使用上,有两种不同目的的接口:PersistentConnection 和 Hubs,其中 PersistentConnection 是实现了长时间的 JavaScript 轮询(类似于 Comet),Hub 是用来解决实时信息交换问题,它是利用 Javascript 动态载入执行方法实现的。SignalR 将整个连接,信息交换过程封装得非常漂亮,客户端与服务器端全部使用 JSON 来交换数据。

四、基本流程图:

               
Paste_Image.png

五、示例:
以下教程我会就 Hubs 接口的使用来做一个实时看板:
示例环境:.NET Framework4.5及以上(必须要) WIN10,Visual Stadio 2017 ,SQL2014.

1、新建项目,打开NuGet包管理器,安装SignalR.最新版本,我这里的版本是V2.2.1.
如图:


       
               
Paste_Image.png

2、 在App_Start目录中,创建一个类,类名为Startup:


       
               
Paste_Image.png

3、 在Startup.cs中注册管道:


       
               
Paste_Image.png

4、设置webconfig。建立一个类DB:目的是获取webconfig文件中的数据库连接字符串:


       
               
Paste_Image.png
               
Paste_Image.png

5、 我们需要在Global.asax.cs的Application_Start和Application_End方法中添加以下内容:


       
               
Paste_Image.png

此处的sqlDependency作用:
当被监测的数据库中的数据发生变化时,SqlDependency会自动触发OnChange事件来通知应用程序,从而达到让系统自动更新数据(或缓存)的目的。详情看第8步。

6、建个Model,TableA。这里就只有X,Y,Z三个字段:


       
               
Paste_Image.png

       

再到数据库中建立相对于的数据库和表。
注意:建完表后记得启动SQL Server Service Broker。
启动SQL Server Service Broker 其中([SignalR]为数据库名)
ALTER DATABASE [SignalR] SET NEW_BROKER WITH ROLLBACK IMMEDIATE;
ALTER DATABASE [SignalR] SET ENABLE_BROKER;

7、在项目录中,创建一个SignalR目录,我们就可以在这个目录中添加Hub类了:


       
               
Paste_Image.png

       

记得使用小驼峰命名,不然客户端调用不了。

8、实现去数据库获取数据,当数据库的数据变化时,客户端也能实时显示:


       
               
Paste_Image.png
               
Paste_Image.png

       

其中以下代码是根据数据库检测到的变化的内容触发OnChange事件。
SqlDependency dependency = new SqlDependency(sqlCommand);
dependency.OnChange += new OnChangeEventHandler(dependency_Onchange);

9、建一个控制器:两个Action操作


       
               
Paste_Image.png

10、视图:


       
               
Paste_Image.png
               
Paste_Image.png
               
Paste_Image.png

到了,到此为止本教程基本结束了,下面将会是本教程的实际效果。

这是数据库中这张表的数据


       
               
Paste_Image.png

现在把第二行第二列的5修改为9。


       
               
Paste_Image.png

由此可见所有连接的客户端的值也跟着改变了,这样实时推送的功能也就实现了。
好了,关于SignalR的相关内容就介绍那么多了,更多SignalR的技术内容大家也可以自行挖掘一下。

               
35人点赞            
               
后台开发            
               
更多精彩内容,就在简书APP
"小礼物走一走,来简书关注我"
  共1人赞赏        
         
何向宇Swift C# .Net技术 HTML5+CSS3 程序员            
总资产17共写了8368字获得145个赞共85个粉丝            


   


全部评论10只看作者            
按时间倒序
按时间正序

               
大麦子就是我                    
11楼                         
看望坚持笔耕的何向宇,一起加油 我的原创童话公众号:麦三山 期待互关~~~~~
 赞 回复                        
               
97379c573410                    
10楼                         
楼主,SignalR支持android https么?用http访问可以,换https就没反应了。请楼主赐教。
 赞 回复                        
               
               
请注意你的素质啊                    
9楼                         
楼主,当数据库数据发生变化的时候,你这个getData()会被执行多次。(有时是3次,有时10几次,甚至会不停执行)。 按理说数据库发生变化时这个方法只执行一次就可以了。
 赞 回复                        
               
dwademan                    
8楼                         
楼主,我解决问题了,sqldependency.onchange事件的问题,我在数据库检索指令里面多加了一个搜索条件,导致onchang出了点问题,谢谢你的文章
 赞 回复                        
               
dwademan                    
7楼                         
我试过网上进入change事件后,有对SqlNotificationEventArgs.type进行判定的,当e.Type == SqlNotificationType.Change,再进行更新的,但是我也没试出来。
我觉得用了"using(){}"方法后,每次执行完,就自动释放了“sqlDependency.OnChange”注册的事件,这样也谈不上再去处理事件了。
所以是不是应该建一个单步的线程,注册完“sqlDependency.OnChange”就一直挂在那边。。。
今天有点晚了,我没时间验证我的想法了,改天试了再发你,总觉得网上贴出来的东西都差不多,理解上去理解不同。
 赞 回复                        
               
dwademan                    
6楼                         
楼主,你好,我今天也借用了你的源码测试了一下,我试下来的结果是页面一直不停的再更新,我是初学者,我说下我理解不停更新的原因,有误的话还望指教。
你程序是个死循环:进入页面时,触发“getData()”,此时通过Json新建"TableAEntity"实例并调用内部“GetData()”方法,“GetData()”方法里添加Onchange事件,并读取数据库内容返回。
这样你程序里一方面用“GetData()”返回数据给力页面,另外一方面"dependency_Onchange"事件又触发了(我试下来不管数据有无更新,事件都会触发,我断点查看了下事件内SqlNotificationEventArgs.type,等于subscribe,订阅的意思),事件触发通过signalr再次让页面执行“getData()”,等于是回到了开始刚进页面的时候。
这样方法上确实是能实时更新数据数据,因为一直在读取数据库内容,数据库内容变了,页面也会更新,但好像跟SqlDependency没关系了,“dependency_Onchange”事件每次都在新建并执行。
 赞 回复                        
               
小明yz                    
4楼                         
不错
 赞 回复                        
               
WithLin                    
3楼                         
数据库的连接一直在?这样对程序对数据的性能造成很大的消耗啊
 赞 回复                        
                               
何向宇作者                                    
连着只是和底层连着,底层实例只有一个也就是一个连接,数据库监测表是否有更新是数据库的功能,在没有其他查询操作的时候是没有很大的消耗的吧。
 回复                                
 添加新评论                    
               
10dd2f756cbf                    
2楼                         
又学到新知识了,感谢分享!期待你更多的文章呀~
 赞 回复                        


被以下专题收入,发现更多相似内容    



普通分类: