SignalR 进阶

发布时间 2023-07-10 18:37:46作者: 广州大雄

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

image

hub获取access_token验证

image

自定义生成access_token方法与验证access_token方法即可。

signalR 横向扩展

image
image

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