SignalR 进阶
SignalR 客户端使用 WebSocket 的条件
客户端浏览器需要支持 WebSocket:WebSocket 是一种 HTML5 的新技术,因此要使用 WebSocket,客户端浏览器必须支持 WebSocket 协议。大多数现代浏览器都已经支持了 WebSocket,包括 Chrome、Firefox、Safari 等。
WebSocket 具有以下几个优点:
-
双向通信:WebSocket 可以在客户端和服务器之间建立双向通信的连接。相比传统的 HTTP 请求-响应模式,WebSocket 允许服务器主动推送数据给客户端,实现实时的双向通信。
-
实时性:WebSocket 提供了一种低延迟、高效率的实时通信机制。与轮询或长轮询等传统的实时通信方式相比,WebSocket 可以更快速地传输数据,降低了通信的延迟,使得实时应用更加流畅和响应迅速。
-
较少的开销:WebSocket 使用较少的网络带宽和服务器资源。由于 WebSocket 是基于长连接的,不需要每次通信都建立新的连接,而是通过一个持久的连接进行数据传输,减少了每次连接的开销。
-
更好的兼容性:WebSocket 是标准化的协议,被广泛支持。现代的浏览器都支持 WebSocket,而且常见的服务器技术也提供了对 WebSocket 的支持。这为开发者提供了更好的兼容性和跨平台的能力。
SignalR服务可以与http服务部署在同一个站点
当你将 SignalR 服务部署到与 HTTP 服务相同的站点时,可以使用同一个域名和端口来访问它们。这种方式可以让客户端从同一个站点直接与 SignalR 服务建立连接,无需跨域访问,减少了跨域访问带来的额外配置和复杂性。
Hub常用事件
在 SignalR 中,可以使用事件处理程序来处理并响应 SignalR Hub 的各种事件。以下是一些常用的 SignalR 事件处理程序:
OnConnectedAsync:当客户端成功连接到 SignalR Hub 时触发。可以在此处执行初始化操作、记录连接日志等。
public override Task OnConnectedAsync()
{
// 在客户端连接成功时执行的逻辑代码
return base.OnConnectedAsync();
}
OnDisconnectedAsync:当客户端与 SignalR Hub 断开连接时触发。可以在此处执行清理操作、更新状态等。
public override Task OnDisconnectedAsync(Exception exception)
{
// 在客户端断开连接时执行的逻辑代码
return base.OnDisconnectedAsync(exception);
}
自定义的客户端-服务器方法:您可以定义自己的方法,使客户端能够调用这些方法,而服务器可以通过事件处理程序来响应这些方法的调用。
public async Task SendMessage(string user, string message)
{
// 处理客户端发送的消息
await Clients.All.SendAsync("ReceiveMessage", user, message);
}
OnReconnectedAsync:当客户端在断开连接后重新连接到 SignalR Hub 时触发。可以在此处执行恢复操作、更新状态等。
public override Task OnReconnectedAsync()
{
// 在客户端重新连接时执行的逻辑代码
return base.OnReconnectedAsync();
}
您可以根据需要选择和实现适当的事件处理程序来处理客户端与 SignalR Hub 之间的连接、断开连接和通信事件。这些事件处理程序可以通过重写 Hub 类中定义的相应方法来实现。
signalR 身份验证和授权
如果觉得官方的jwt方案,比较麻烦,也可以自己实现。
JS端传输access_token
hub获取access_token验证
自定义生成access_token方法与验证access_token方法即可。
signalR 横向扩展
SignalR 目前提供三个底板:
- Azure 服务总线。 服务总线是一种消息传送基础结构,允许组件以松散耦合的方式发送消息。
- Redis。 Redis 是内存中键值存储。 Redis 支持用于发送消息的发布/订阅 (“pub/sub”) 模式。
- SQL Server。 SQL Server底板将消息写入 SQL 表。 底板使用 Service Broker 进行高效的消息传送。 但是,如果未启用 Service Broker,它也有效。
实现原理
-
在 SignalR 中,每条消息都通过消息总线发送。 消息总线实现 IMessageBus 接口,该接口提供发布/订阅抽象。 底板的工作原理是将默认 的 IMessageBus 替换为为该底板设计的总线。 例如,Redis 的消息总线是 RedisMessageBus,它使用 Redis 发布/订阅 机制来发送和接收消息。
-
每个服务器实例通过总线连接到底板。 发送消息时,消息将转到底板,底板将消息发送到每个服务器。 当服务器从底板获取消息时,它会将消息放入其本地缓存中。 然后,服务器将消息从其本地缓存传递到客户端。
-
对于每个客户端连接,使用游标跟踪客户端读取消息流的进度。 (游标表示消息流中的位置。) 如果客户端断开连接,然后重新连接,它会要求总线提供客户端游标值之后到达的任何消息。 当连接使用 长时间轮询时,也会发生同样的情况。 长时间轮询请求完成后,客户端将打开一个新连接,并请求在游标之后到达的消息。
-
即使客户端在重新连接时路由到其他服务器,游标机制也有效。 底板可识别所有服务器,客户端连接到哪个服务器并不重要。
参考
https://learn.microsoft.com/zh-cn/aspnet/signalr/overview/performance/scaleout-in-signalr