SignalR 简介
什么是 SignalR?
ASP.NET SignalR 是 ASP.NET 开发人员的库,可简化将实时 web 功能添加到应用程序的过程。 实时 web 功能使服务器代码能够在可用时立即将内容推送到连接的客户端,而不是让服务器等待客户端请求新的数据。
SignalR 可用于将任何种类的 "实时" web 功能添加到 ASP.NET 应用程序。 尽管聊天通常用作示例,但你可以执行更多操作。 用户每次刷新网页以查看新数据,或者页面实现长轮询来检索新数据时,都是使用 SignalR 的候选项。 示例包括仪表板和监视应用程序、协作应用程序(如同步编辑文档)、作业进度更新和实时窗体。
SignalR 还启用了全新类型的 web 应用程序,这些应用程序需要服务器中的高频率更新,例如,实时游戏。
SignalR 提供了一个简单的 API,用于创建从服务器端 .NET 代码调用客户端浏览器(和其他客户端平台)中的 JavaScript 函数的服务器到客户端远程过程调用(RPC)。 SignalR 还包括用于连接管理的 API (例如,连接和断开连接事件)以及对连接进行分组。
SignalR 自动处理连接管理,让你可同时向所有连接的客户端广播消息,就像聊天室一样。 也可以向特定客户端发送消息。 客户端和服务器之间的连接是持久的,不同于传统的 HTTP 连接,后者针对每次通信重新建立。
SignalR 支持 "服务器推送" 功能,在此功能中,服务器代码可以使用远程过程调用(RPC),而不是 web 上常见的请求-响应模型,在浏览器中调用客户端代码。
使用内置和第三方横向扩展提供程序,SignalR 应用程序可以向外扩展到数千个客户端。
内置提供程序包括:
第三方提供程序包括:
SignalR 是开放源代码,可通过GitHub访问。
SignalR 和 WebSocket
SignalR 使用新的 WebSocket 传输(如果可用),并在必要时回退到较旧的传输。 虽然当然,你可以直接使用 WebSocket 编写应用,但使用 SignalR 意味着你需要实现的很多额外功能都已完成。 最重要的是,这意味着您可以对应用程序进行编码,以便利用 WebSocket,而不必担心为较旧的客户端创建单独的代码路径。 SignalR 还会使你不必担心对 WebSocket 的更新,因为 SignalR 会更新为支持基础传输中的更改,从而为你的应用程序提供跨 WebSocket 版本的一致接口。
传输和回退
SignalR 是对在客户端和服务器之间进行实时工作所需的某些传输的抽象。 SignalR 连接以 HTTP 开头,然后将其升级到 WebSocket 连接(如果可用)。 WebSocket 是适用于 SignalR 的理想传输,因为它可以最有效地使用服务器内存,具有最低的延迟,并且具有最基本的功能(如客户端与服务器之间的全双工通信),但它也具有最严格的要求: WebSocket 要求服务器使用 Windows Server 2012 或 Windows 8,并 .NET Framework 4.5。 如果未满足这些要求,SignalR 将尝试使用其他传输进行连接。
HTML 5 传输
这些传输依赖于对HTML 5的支持。 如果客户端浏览器不支持 HTML 5 标准版,将使用较旧的传输。
- Websocket (如果服务器和浏览器均指示它们可以支持 websocket)。 WebSocket 是在客户端与服务器之间建立真正持久的双向连接的唯一传输。 但是,WebSocket 还具有最严格的要求;它仅在最新版本的 Microsoft Internet Explorer、Google Chrome 和 Mozilla Firefox 中完全受支持,并且在某些浏览器(如 Opera 和 Safari)中仅有部分实现。
- 服务器发送事件,也称为 EventSource (如果浏览器支持服务器发送事件,这基本上是 Internet Explorer 之外的所有浏览器。)
Comet 传输
以下传输基于Comet web 应用程序模型,在该模型中,浏览器或其他客户端维护长时间的 HTTP 请求,服务器可以使用该模型将数据推送到客户端,而客户端无需专门请求它。
- 永久帧(仅适用于 Internet Explorer)。 永久帧创建一个隐藏的 IFrame,该 IFrame 向服务器上不能完成的终结点发出请求。 服务器随后会持续向客户端发送脚本,该脚本会立即执行,提供从服务器到客户端的单向实时连接。 从客户端到服务器的连接使用与服务器之间的单独连接连接到客户端连接,与标准 HTTP 请求一样,为需要发送的每个数据段创建新连接。
- Ajax 长轮询。 长轮询不会创建持续性连接,而是使用保持打开状态的请求轮询服务器,直到服务器响应为止,此时连接将关闭,并立即请求新连接。 在连接重置时,这可能会导致一些延迟。
有关在哪些配置下支持哪些传输的详细信息,请参阅支持的平台。
传输选择过程
以下列表显示了 SignalR 用于确定要使用的传输的步骤。
- 如果浏览器是 Internet Explorer 8 或更早版本,则使用长轮询。
- 如果配置了 JSONP (即,在启动连接时
jsonp
参数设置为true
),则使用长轮询。 - 如果正在建立跨域连接(即,如果 SignalR 终结点与宿主页不在同一个域中),则在满足以下条件时将使用 WebSocket:
- 客户端支持 CORS (跨域资源共享)。 有关哪些客户端支持 CORS 的详细信息,请参阅caniuse.com 上的 cors。
- 客户端支持 WebSocket
- 服务器支持 WebSocket
如果未满足这些条件中的任何一个,将使用长轮询。 有关跨域连接的详细信息,请参阅如何建立跨域连接。
- 如果未配置 JSONP 并且连接不跨域,则在客户端和服务器均支持时,将使用 WebSocket。
- 如果客户端或服务器不支持 WebSocket,则使用服务器发送事件(如果可用)。
- 如果 "服务器发送事件" 不可用,则将尝试永久帧。
- 如果永久帧失败,则使用长轮询。
监视传输
可以通过在中心启用日志记录,并在浏览器中打开控制台窗口,来确定应用程序使用的传输方式。
若要在浏览器中为中心的事件启用日志记录,请将以下命令添加到客户端应用程序:
$.connection.hub.logging = true;
- 在 Internet Explorer 中,按 F12 打开开发人员工具,然后单击 "控制台" 选项卡。
- 在 Chrome 中,按 Ctrl + Shift + J 打开控制台。
启用控制台打开并启用日志记录后,你将能够查看 SignalR 所使用的传输。
指定传输
协商传输会占用一定的时间和客户端/服务器资源。 如果客户端功能已知,则可以在启动客户端连接时指定传输。 下面的代码段演示如何使用 Ajax 长轮询传输开始连接,如果已知客户端不支持任何其他协议,则使用该连接:
connection.start({ transport: ‘longPolling‘ });
如果希望客户端按顺序尝试特定传输,可以指定回退顺序。 下面的代码片段演示了如何尝试 WebSocket,并失败了,这将直接转到长轮询。
connection.start({ transport: [‘webSockets‘,‘longPolling‘] });
用于指定传输的字符串常量定义如下:
webSockets
foreverFrame
serverSentEvents
longPolling
连接和集线器
SignalR API 包含两种用于在客户端和服务器之间进行通信的模型:持久性连接和中心。
连接表示用于发送单接收方、分组或广播消息的简单终结点。 持久性连接 API (在 .NET 代码中由 PersistentConnection 类表示)使开发人员能够直接访问 SignalR 公开的低级别通信协议。 使用基于连接的 Api (如 Windows Communication Foundation)的开发人员将对使用连接通信模型非常熟悉。
中心是一种基于连接 API 构建的更高级别管道,它允许客户端和服务器直接调用方法。 SignalR 按魔术处理跨计算机边界的调度,使客户端能够像本地方法一样轻松地调用服务器上的方法,反之亦然。 如果开发人员已使用远程调用 Api (如 .NET 远程处理),则将对使用中心通信模型非常熟悉。 使用集线器还可以将强类型参数传递给方法,从而启用模型绑定。
体系结构关系图
下图显示了集线器、永久性连接和用于传输的底层技术之间的关系。
集线器的工作方式
服务器端代码在客户端上调用方法时,会在活动传输中发送一个数据包,其中包含要调用的方法的名称和参数(当对象作为方法参数发送时,将使用 JSON 进行序列化)。 然后,客户端将方法名称与在客户端代码中定义的方法相匹配。 如果存在匹配项,则将使用反序列化的参数数据执行客户端方法。
可以使用 Fiddler 等工具监视此方法调用。 下图显示了在 Fiddler 的 "日志" 窗格中从 SignalR 服务器发送到 web 浏览器客户端的方法调用。 将从名为 MoveShapeHub
的中心发送方法调用,调用的方法 updateShape
。
在此示例中,用 H
参数标识中心名称;方法名称用 M
参数标识,发送到方法的数据通过 A
参数进行标识。 生成此消息的应用程序将在高频实时教程中创建。
选择通信模型
大多数应用程序应使用中心 API。 连接 API 可用于以下情况:
- 需要指定所发送的实际邮件的格式。
- 开发人员首选使用消息传递和调度模型,而不使用远程调用模型。
- 使用消息传送模型的现有应用程序正在移植,以使用 SignalR。
原文地址:https://www.cnblogs.com/alvin2013/p/12340890.html