代码人生

SignalR介绍简单示例教程入门版

代码人生 http://www.she9.com 2018-04-26 08:50 出处:网络 编辑:@霜伤
ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程。实时 Web 功能是指这样一种功能:当所连接的客户端变得可用时服务器代码可以立即向其推送内容,而不是让服务器等待客户端请求新的数据。

ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信。什么是实时通信的Web呢?就是让客户端(Web页面)和服务器端可以互相通知消息及调用方法,当然这是实时操作的。

WebSockets是HTML5提供的新的API,可以在Web网页与服务器端间建立Socket连接,当WebSockets可用时(即浏览器支持Html5)SignalR使用WebSockets,当不支持时SignalR将使用其它技术来保证达到相同效果。

SignalR当然也提供了非常简单易用的高阶API,使服务器端可以单个或批量调用客户端上的JavaScript函数,并且非常 方便地进行连接管理,例如客户端连接到服务器端,或断开连接,客户端分组,以及客户端授权,使用SignalR都非常 容易实现。

SignalR 将与客户端进行实时通信带给了ASP .NET 。当然这样既好用,而且也有足够的扩展性。以前用户需要刷新页面或使用Ajax轮询才能实现的实时显示数据,现在只要使用SignalR,就可以简单实现了。

最重要的是您无需重新建立项目,使用现有ASP .NET项目即可无缝使用SignalR。


最近因为项目中涉及到了实时数据的传输,特地去了解了一下当前Web应用中常见的实时交互手段,当然一开始也不仅限于Web客户端。从c#自带的Socket类,到Html5中的WebSocket,再到Asp .Net利器SignalR,总算将这块知识点及应用入门了,当然今天的主要内容还是Web端的消息交互技术(Ajax,Comet,WebSocket等),这些技术难度有中有低,应用场所也有不同,最后我们要根据项目情况来选择恰当的技术。接下来便简单介绍一下


Web消息交互技术


 常见技术


应用技术说明优缺点
轮询(polling)这应该是最常见的一种实现数据交互的方式,开发人员控制客户端以一定时间间隔中向服务器发送Ajax查询请求大,但是也因此,当服务器端内容并没有显著变化时,这种连接方式将带来很多无效的请求,造成服务器资源损耗。适合并发量小,实时性要求低的应用模型,更像是定时任务。优点:实现最为简单,配置简单,出错几率小 

缺点:每次都是一次完整的http请求,易延迟,有效请求命中率少,并发较大时,服务器资源损耗大
长轮询(long polling)长轮询是对轮询的改进,客户端通过请求连接到服务器,并保持一段时间的连接状态,直到消息更新或超时才返回Response并中止连接,可以有效减少无效请求的次数。属于Comet实现优点:有效减少无效连接,实时性较高 

缺点:客户端和服务器端保持连接造成资源浪费,服务器端信息更新频繁时,long polling并不比polling高效,并且当数据量很大时,会造成连续的polls不断产生,性能上反而更糟糕
iframe流iframe流方式是在页面中插入一个隐藏的iframe,利用其src属性在服务器和客户端之间创建一条长链接,服务器向iframe传输数据(通常是HTML,内有负责插入信息的javascript),来实时更新页面。属于Comet实现优点:实时性高,浏览器兼容度好 

缺点:客户端和服务器端保持长连接造成资源浪费
WebSocketWebSocket是HTML5提供的一种在单个 TCP 连接上进行全双工通讯的协议,目前chrome、Firefox、Opera、Safari等主流版本均支持,Internet Explorer从10开始支持。另外因为WebSocket 提供浏览器一个原生的 socket实现,所以直接解決了 Comet 架构很容易出错的问题,而在整個架构的复杂度上也比传统的实现简单得多。优点:服务器与客户端之间交换的数据包档头很小,节约带宽。全双工通信,服务器可以主动传送数据给客户端。 

缺点:旧版浏览器不支持

Comet 简介

浏览器作为 Web 应用的前台,自身的处理功能比较有限。浏览器的发展需要客户端升级软件,同时由于客户端浏览器软件的多样性,在某种意义上,也影响了浏览器新技术的推广。在 Web 应用中,浏览器的主要工作是发送请求、解析服务器返回的信息以不同的风格显示。AJAX 是浏览器技术发展的成果,通过在浏览器端发送异步请求,提高了单用户操作的响应性。但 Web 本质上是一个多用户的系统,对任何用户来说,可以认为服务器是另外一个用户。现有 AJAX 技术的发展并不能解决在一个多用户的 Web 应用中,将更新的信息实时传送给客户端,从而用户可能在“过时”的信息下进行操作。而 AJAX 的应用又使后台数据更新更加频繁成为可能。

WebSocket介绍


WebSocket本质上是一个基于TCP的持久化协议,相对于HTTP这种非持久的协议来说,它能够更好的节省服务器资源和带宽,并且真正实现实时通信。以下是它与传统技术的性能对比图(Websocket.org提供)

SignalR介绍简单示例教程入门版


SignalR介绍简单示例教程入门版


我们可以看到相比于传统技术,在流量和负载逐渐增大时,WebSocket的性能表现是远远超过它们的。



SignalR是什么


SignalR是一个.Net开源库,用于构建需要实时进行用户交互和数据更新的Web应用,如在线聊天,游戏,天气或者股票信息更新等实时应用程序。SignalR简化了构建实时应用的过程,它包括了一个Asp .Net服务器端库和一个Js端库,集成了数种常见的消息传输方式,如long pollingWebSocket,并提供相应的Api供开发人员选择如何调用,帮助其可以简单快速地实现客户端与服务器端相互间的实时通信。
当环境条件合适时,SignalR将WebSocket作为底层传输方式的优先实现,当然,它也能很高效地回退到其他技术。同时,SignalR提供了非常良好的Api以供远程调用(RPC) 浏览器中的js代码。
接下来,看看SignalR的传输方式和通信模型,这是SignalR的核心所在。

SignalR基本适用于任何可以用上述技术实现的场合,但是对寄宿平台版本有要求。如.Net Framework 平台,SignalR库需要4.5及以上版本的支持,而Mono上也实现了SignalR。如果是最新的.Net Core 1.0,建议大家直接使用SelfHost方式寄宿。


默认传输方式


传输方式选择条件
long polling1.IE8或更早版本 
2.连接启动时JSONP参数设置为TRUE 
3.Forever Frame不可用 
WebSocket1.正在使用跨域连接,并且符合以下条件(以下不满足任一条则使用长轮询) 

(1).客户端支持CORS 
(2).客户端支持WebSocket 
(3).服务器端支持WebSocket 

2.不配置使用JSONP,连接不跨域并且客户端和服务器端都支持WebSocket 

(1).客户端支持CORS 
(2).客户端支持WebSocket 
(3).服务器端支持WebSocket 
ServerSendEvent客户端或服务器端不支持Websocket
Forever FrameEventSource不可用(基本上除了IE外都支持)

自动管理传输方式


不指定传输方式时,SignalR会以Http方式发起请求,比对客户端和服务器端后,假如WebSocket可用,则自动升级到WebSocket模式,WebSocket是最理想的传输方式,除了能高效使用服务器内存,低延迟,还能实现客户端和服务器端的全双工通信。开发人员可以通过SignalR中js库的$.connection.chatHub.logging = true;来启用hub事件的日志记录

通信模型

SignalR包括两种客户端和服务器端之间进行通信的模型,Persistent ConnectionsHubs

通信模型说明
Persistent ConnectionsPersistent Connections表示一个发送单个,编组,广播信息的简单终结点。开发人员通过使用持久性连接Api,直接访问SignalR公开的底层通信协议。
HubsHubs是基于连接Api的更高级别的通信管道,它允许客户端和服务器上彼此直接调用方法,SignalR能够很神奇地处理跨机器的调度,使得客户端和服务器端能够轻松调用在对方端上的方法。使用Hub还允许开发人员将强类型的参数传递给方法并且绑定模型


SignalR具体开发步骤


Hubs的示例网上已经很多了(文章末尾附上链接),这边先来快速开始一个SignalR使用永久连接的Demo.

关于永久连接和Hubs的区别,这里有些很棒的解释.

(1)安装Nuget包


创建一个默认的Asp .Net Mvc项目
使用Install-Package Microsoft.AspNet.SignalR安装SignalR包

(2)增加SignalR服务


新增Connections文件夹,添加SignalR永久连接类ChatConnections

SignalR介绍简单示例教程入门版

using System.Threading.Tasks;using Microsoft.AspNet.SignalR;namespace SignalRUsingPersistentConnectionsDemo.Connections{    public class ChatConnection : PersistentConnection
    {        protected override Task OnConnected(IRequest request, string connectionId)        {            return Connection.Send(connectionId, "Welcome!");
        }        protected override Task OnReceived(IRequest request, string connectionId, string data)        {            return Connection.Broadcast(data);
        }
    }
}

(3)增加Startup启动类


SignalR介绍简单示例教程入门版


using Microsoft.Owin;using Owin;using SignalRUsingPersistentConnectionsDemo;using SignalRUsingPersistentConnectionsDemo.Connections;

[assembly: OwinStartup(typeof (Startup))]namespace SignalRUsingPersistentConnectionsDemo{    public class Startup
    {        public void Configuration(IAppBuilder app)        {            // 有关如何配置应用程序的详细信息,请访问 http://go.microsoft.com/fwlink/?LinkID=316888
            // 配置上文实现的ChatConnections
            app.MapSignalR<ChatConnection>("/Connections/ChatConnection");
        }
    }
}

(4)前端js配置


前端js实现消息广播,并实时记录

@{
    Layout = null;
}<script src="~/Scripts/jquery-1.10.2.min.js"></script><script src="~/Scripts/jquery.signalR-2.2.0.min.js"></script><script type="text/javascript">
    $(function () {        var connection = $.connection("/Connections/ChatConnection");

        $('#displayname').val(prompt('Enter your name:', ''));
        $("msg").focus();

        connection.received(function (data) {
            $('#messages').append('<li>' + data + '</li>');
        });

        connection.start().done(function() {
            $("#broadcast").click(function () {
                connection.send($('#displayname').val()+':'+$('#msg').val());
            });
        });

    });</script><input type="text" id="msg" /><input type="button" id="broadcast" value="broadcast"/><input type="hidden" id="displayname" /><ul id="messages"></ul>

(5)实际效果


SignalR介绍简单示例教程入门版


(6).Net Client实现


除了Web实时应用之外,你也可以用其他应用程序实现实时交互,如控制台。只需要Install-Package Microsoft.AspNet.SignalR.Client命令,示例编码如下

using Microsoft.AspNet.SignalR.Client;using static System.Console;namespace DotnetClientWithSignalRDemo{    internal class Program
    {        private static void Main(string[] args)        {            var connection = new Connection("http://localhost:1508/Connections/ChatConnection");

            connection.Received += WriteLine;
            connection.Start().Wait();            string line;            while ((line = ReadLine()) != null)
            {
                connection.Send(line).Wait();
            }
        }
    }
}

效果如图,同样实现了双向通信

SignalR介绍简单示例教程入门版


简单示例教程入门版

SignalR的简单教程制作一个在线的聊天


  • 前端用了国产的一个MVVM框架 avalon 的早期版本和 layer  插件

  • MVC项目里面新增一个Hub 的继承类 ChatHub , 标签HubName 类似于一个重命名的效果

  • OnlineCache 类的作用是定义了一个KEY和VALUE主要用于记录用户名称和Signalr自动生成的KEY关系

  •  Startup.cs   里记得注册下 app.MapSignalR();

SignalR介绍简单示例教程入门版

[HubName(   Send( name, 
        
          Push( (!OnlineCache.dicSignalrs.ContainsKey(
        
        
           
        
        
        
         
         
         
         
          Task OnDisconnected( (OnlineCache.dicSignalrs.ContainsKey( name = OnlineCache.dicSignalrs[ 
        
        
              Key { ;   Value { ;  (dicSignalrs == =  Dictionary<, >  Dictionary<, > 
         
         
          List<OnlineCache> OnlineToList() => dicSignalrs.Select(o =>  OnlineCache() { Key = o.Key, Value =

SignalR介绍简单示例教程入门版


前端JS脚本

SignalR介绍简单示例教程入门版

     
    Index
     
     
     

    
    
    


    
    

    
    
         
                              
    
        在线用户列表
        
        
            
        
    
    
        
        
        
        
            
                
                    
                        
                            发送人
                            内容
                        
                        
                            {{el.name}}
                            {{el.message}}
                        
                    
                
            
        
    
    
        
        
             
        
        
        
        
            账号昵称:{{customname}}
        
        
        
        
            发送对象:{{sendname}}


请关注公众号:程序你好
0

精彩评论

暂无评论...
验证码 换一张
取 消