一.导言
Signal是微软支持的一个html websocket框架,运行在Dot NET平台上。它出现的主要目的是使服务器能够主动将消息推送到客户端页面,这样客户端就不需要重新发送请求或使用轮询技术来获取消息。你可以访问它的官方网站:https://github.com/SignalR/了解更多信息。
二、什么是Asp.net信号员
Asp.net信号器是微软实现实时通信的类库。一般SignalR会利用JavaScript的长轮询来实现客户端和服务器端的通信。随着Html5中WebSockets的出现,SignalR也支持WebSockets通信。此外,SignalR开发的程序并不局限于在IIS中托管,还可以在任何应用程序中托管,包括控制台、客户端程序和Windows服务等。此外,它还支持Mono,这意味着它可以跨平台部署在Linux环境中。
信号内部有两种对象:
Http Persisten Connection对象:用于解决长期连接的函数。客户端也可以主动向服务器请求数据,但是服务器不需要实现太多的细节,只需要处理PersistentConnection中提供的五个事件:on connected、on reconned、on received、on error和OnDisconnect。Hub (Hub)对象:用于解决实时信息交换的功能。服务器可以通过网址注册一个或多个集线器。只要连接到该集线器,它就可以与所有客户端共享发送到服务器的信息。同时,服务器可以调用客户端的脚本。SignalR封装了整个信息交换,客户端和服务器端都使用JSON进行通信。服务器上声明的所有Hub信息将生成JavaScript并将其输出到客户端.NET依赖于proxy来生成Proxy对象,而Proxy在内部将JSON转换为对象。由于SignalR是为实时而生的,它决定了它的使用场所。具体应用场景如下:聊天室,如在线客服系统、IM系统等。游戏中角色位置的实时推送。目前,我公司正在开发一个在线客户服务系统。
三、实现机制
SignalR的实现机制类似于。NET WCF或远程处理,这是通过使用远程代理实现的。具体使用上,有两种不同用途的接口:PersistentConnection和Hubs,其中PersistentConnection实现长时间的Javascript轮询(类似Comet),Hub解决实时信息交换的问题,使用Javascript动态加载和执行的方法实现。SignalR将整个连接和信息交换过程封装得非常精美,客户端和服务器端都使用JSON进行数据交换。
让我们从使用集线器接口的角度来谈谈整个过程:1。在服务器端定义相应的集线器类;2.在客户端定义与中心类对应的代理类;3.建立连接);在客户端和服务器之间;4.然后客户端可以调用代理对象的方法来调用服务器的方法,即向服务器发送请求;5.收到请求后,服务器可以向某个/某组客户端或所有客户端发送消息(广播)。
第四,使用Asp.net信号器在网络端广播消息
通过第二部分的介绍,相信大家对Asp.net通信兵有了一个初步的了解,接下来我们将通过两个例子加深对通信兵运行机制的理解。第一个例子是如何使用SignalR在Web端广播消息。使用Visual Studio 2013创建一个MVC项目,并通过Nuget安装SignalR包。右键单击引用-“选择管理数字包-”并在窗口中输入信号,找到要安装的信号包。成功安装信号程序后,信号程序库的脚本将被添加到脚本文件夹中。具体如下图所示:
向项目中添加一个信号集线器(v2),并将其命名为服务器集线器。
将以下代码填充到刚刚创建的ServerHub类中。
使用系统;使用微软。信号员;命名空间信号演示{公共类服务器集线器:集线器{私有静态只读字符[]常量={ '0 ',' 1 ',' 2 ',' 3 ',' 4 ',' 5 ',' 6 ',' 7 ',' 8 ',' 9 ',' A ',' B ',' C ',' D ',' F ',' G ',' H ',' I ',' J ',' K ',' L ',' N ',' P ',' Q ',' R ',' S ',' T ',' U ',' V ',' W ',' X ',' Y ',' Z '摘要///供客户端调用的服务器端代码////summary///param name=' message '/param public void Send(字符串消息){ var name=GenerateRandomName(4);//调用所有客户端的发送消息方法客户全部.发送消息(名称,消息);} ///摘要///产生随机用户名函数////summary///param name=' length '用户名长度/param /返回/返回公共静态字符串生成器名称(整数长度){ var new random=新系统.文字。StringBuilder(62);var rd=new Random();for(var I=0;一、长度;i ) { newRandom .追加(常量[rd .下一个(62)];}返回纽兰登.ToString();} }}创建一个启动类,如果开始创建手动音量调节项目的时候没有更改身份验证的话,这个类会默认添加的,如果已有就不需要重复添加了。按照如下代码更新启动类。
使用微软哦.使用owin[assembly : OwInstarToPattribute(类型为(SignalDemo .启动))]命名空间SignalDemo{公共分部类启动{ # region my region public void Configuration(IAppBuilder应用程序){ app .mapsignor();配置验证(应用程序);} #endregion }}在主页控制器中创建一个聊天动作方法
使用系统网络。手动音量调节命名空间信号演示.控制器{公共类家庭控制器:控制器{公共操作结果聊天(){返回视图();} }}在视图文件中主页文件夹中创建一个闲谈视图,视图代码如下所示:
@{ ViewBag .标题='聊天;}h2Chat/h2div class='container '输入类型='text' id='message' /输入类型='button' id='sendmessage '值='发送'/输入类型=' hidden ' id=' display name '/ul id=' discussion '/ul/div @ section scripts {!-引用信号员库. script-src=' http : ~/Scripts/jquery。二号先生。2 .1 .量滴js '/脚本!-引用自动生成的信号员集线器(集线器)脚本。在运行的时候在浏览器的来源下可看到-script src=' http : ~/signor/hubs '/script script $(function(){//引用自动生成的集线器代理var chat=$。连接。serverhub//定义服务器端调用的客户端发送消息来显示新消息chat.client.sendMessage=函数(名称,消息){ //向页面添加消息$(' #讨论').追加(“listrong”HTMlencode(name)'/strong :“HTMlencode(message)'/Li ');};//设置焦点到输入框$('#message ').焦点();//开始连接服务器$.connection.hub.start().done(function(){ $(' # send message ')).单击(函数(){ //调用服务器端集线器的发送方法chat . server . send($(“# message”).val());//清空输入框信息并获取焦点$('#message ').val(" ")。焦点();});});});//为显示的消息进行超文本标记语言编码函数htmlEncode(value){ var encodedValue=$(' div/').文本(值)。html();返回编码值;} /script}修改应用程序_开始文件夹内的路由配置类,将行动方法默认设置为闲谈
使用系统网络。手动音量调节使用系统。网络路由;命名空间SignalDemo{公共类路线图公共静态作废注册路线(路线收集路线){路线} .忽略重路由(' {resource}).axd/{ * PathInfo } ');路线MapRoute(名称: 'Default ',URL : " { controller }/{ action }/{ id } ",Default s 3360 new { controller=' Home ',action='Chat ',id=UrlParameter .可选});} }}到此,我们的例子就实现完成了,接下来我们先来看看运行效果,之后再来解释到底信号员是如何来完成广播消息的。运行的运行结果如下。
从运行结果,你可以发现,在任何一个窗口输入信息并发送,所有客户端将收到该消息。这样的效果在实际应用中很多,如QQ,一登录即时通信软件的时候都会推送腾讯广告消息。
阅读运行结果后,让我们分析代码,然后分析SignalR是如何工作的。
按照B/S模式,运行程序时,网页与SignalR服务建立连接,建立连接的具体代码为$.connection.hub.start()。该代码的功能是建立与信号服务的连接。“稍后完成”功能表示在成功建立连接后,为发送按钮注册了一个单击事件。当客户端输入内容并点击发送按钮时,点击事件将被触发。触发的操作是chat.server.send ($ ('# message ')。val())。这段代码的意思是调用服务器的send函数,服务器的Send朝鲜语版本调用所有客户端的sendMessage函数,而客户端中的sendMessage函数将信息添加到对应的消息列表中。这样就实现了广播消息的功能。
看到这里,有人有疑问吗?前面的实现只使用中心对象,而不使用持久连接对象。事实上,情况并非如此。$的代码。连接是使用持久连接对象。当然,您也可以在OnConnected方法中检查监控客户端的连接状态。更新后的代码如下:
公共类ServerHub : Hub { private static readonly char[]Constant={ ' 0 ',' 1 ',' 2 ',' 3 ',' 4 ',' 5 ',' 6 ',' 7 ',' 8 ',' 9 ',' A ',' B ',' C ',' D ',' E ',' F ',' G ',' J ',' K ',' L ',' M ',' N ',' O ',' Q ',' R ',' S ',' T ',' U ',' V ',' W ',' X ',' Y ',' Z ',' A ',' B ',' C ',' D ',///summary////客户端调用的服务器端代码////summary////param name=' message '/param public void send(字符串消息){ var name=generaterandomname(4);//调用所有客户端的sendMessage方法clients.all.sendmessage(名称、消息);}///summary////call////summary///returns/returns connected()上的公共重写任务{trace。writeline(“客户端连接成功”);返回基地。OnConnected();}///summary////生成随机用户名函数/////summary//param name=' length '用户名length/param///返回/返回公共静态字符串generaterandomname(int length){ var new random=new System。text . StringBuilder(62);var rd=new Random();for(var I=0;一、长度;i ) { newRandom。追加(常量[rd。下一个(62)];}返回newRandom。ToString();}}这样,在运行页面时,就会在输出窗口看到“客户端连接成功”的字样。运行效果如下图所示:
在第二部分的介绍中,说到服务器上声明的所有Hub信息都会生成JavaScript并输出到客户端。要验证这一点,可以在Chrome中查看F12中的源代码,如下图所示:
看到上面的图片,你就能理解为什么Chat.cshtml页面需要引入‘signor/hubs’脚本库了。
!-参考信号库。-Script src=' http : ~/scripts/jquery。signor-2 . 2 . 0 . min . js '/脚本!-参考自动生成的信号中枢脚本。运行时,可以在浏览器的Source-script src=' http : ~/signar/hubs '/脚本下看到
5.如何在桌面程序中使用Asp.net信号
以上部分介绍了signor在Asp.net MVC中的实现,这部分将以一个例子来看看signor在WPF或者WinForm中是如何使用的。事实上,这部分实现与Asp.net的MVC非常相似。主要区别是Asp.net MVC中的Signaler服务器托管在IIS中,而在WPF,我们托管WPF客户端的Signaler。
让我们来看看SignalR服务器的实现。
///摘要///启动信号员服务,将信号员服务寄宿在WPF程序中////summary private void StartServer(){ try { signor=WebApp .start(Serveruri);//启动信号员服务} catch(TargetinvocationException){ Writetontosole('一个服务已经运行在:' Serveruri);//调度员回调来设置用户界面控件状态这个。调度程序。调用(()=按钮启动等熵d=真);返回;}这个。调度程序。调用(()=按钮停止等熵d=真);WriteToConsole(')服务已经成功启动,地址为:' Serveruri);}公共类ChatHub : Hub {公共作废发送(字符串名称,字符串消息){客户.All.addMessage(名称,消息);}公共覆盖任务OnConnected() { //应用程序。当前。调度程序。调用(()=((主窗口)应用程序。当前主窗口)。WriteToConsole(')客户端连接,连接身份是: '上下文ConnectionId));返回基地OnConnected();}公共覆盖任务已连接(bool StOpcalled){ 0应用程序。当前。调度程序。调用(()=((主窗口)应用程序。当前主窗口)。WriteToConsole(')客户端断开连接,连接身份是: '上下文ConnectionId));返回基地OnDisconnected(真);} }公共类启动{公共void Configuration(IAppBuilder应用){//有关如何配置应用程序的详细信息,请访问http://go.microsoft.com/fwlink/?LinkID=316888/允许克-奥二氏分级量表跨域//app .用户界面.允许穿墙);应用程序.mapsignor();} }通过上面的代码,我们信号员服务端的实现就完成了,其实现逻辑与Asp.net最有价值球员的代码类似。
接下来,让我们看看,WPF客户端是如何连接和与服务器进行通信的。具体客户端的实现如下:
public IHubProxy HubProxy { get设置;} const string Serveruri=' http://localhost :8888/signal r ';公共HubConnection Connection { get设置;}公共主窗口(){ InitializeComponent();//窗口启动时开始连接服务ConnectAsync();} ///摘要///发送消息////summary////param name=' sender '/param///param name=' e '/param private void按钮send _ Click(对象发件人,RoutedEventArgs e) { //通过代理来调用服务端的发送方法//服务端发送方法再调用客户端的添加消息方法将消息输出到消息框中HubProxy .调用('发送,生成器名称(4),文本框消息文本。trim());文本框消息。文本=字符串。空的;文本框消息。焦点();} private async void ConnectAsync(){ Connection=new HubConnection(Serveruri);连接。关闭=连接_关闭;//创建一个集线器代理对象集线器代理=连接createHubProxy(' ChatHub ');//供服务端调用,将消息输出到消息列表框中HubProxy .Onstring,string('AddMessage ',(name,message)=this .调度员。调用(()=richtextbox控制台.附录文本(字符串。格式(' {0}: {1}r ',名称,消息)));尝试{等待连接start();} catch(HttprequestException){//连接失败返回;} //显示聊天控件聊天面板。可见度=可见度。可见;按钮发送IsEnabled=真文本框消息。焦点();RichTextBoxConsole .' AppendText('连上服务:' ServerURi ' r ');}上面的代码也就是WPF客户端实现的核心代码,主要逻辑为,客户端启动的时候就调用连接。开始方法与服务器进行连接。然后通过HubProxy代理类来调用集线器中发送方法,而集线器中的发送方法又通过调用客户端的添加消息方法将消息输出到客户端的消息框中进行显示,从而完成消息的推送过程。接下来,让我们看看其运行效果:
从上面的运行效果看出,其效果和Asp.net最有价值球员上的效果是一样的。
总结
到这里,本专题的所有内容就结束了,这篇信号员快速入门也是本人在学习信号员过程中的一些心得体会,希望可以帮助一些刚接触信号员的朋友快速入门。本篇主要实现了信号员的广播消息的功能,可以实现手机端消息推送的功能,接下来一篇将介绍如何使用信号员实现一对一的聊天。
源代码下载:http://xiazai.jb51.net/201609/yuanma/ASP.NETSignalDemo.rar
以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。