当前位置: 首页 > news >正文

SignalR 协议深度分析

1. 握手协议 (Negotiation)

1.1 客户端发起握手

POST /chathub/negotiate HTTP/1.1
Host: localhost:5000
Content-Type: application/json
Connection: keep-alive{"protocol": "json","version": 1
}

1.2 服务器响应

HTTP/1.1 200 OK
Content-Type: application/json{"connectionId": "abc123","availableTransports": [{"transport": "WebSockets","transferFormats": ["Text", "Binary"]},{"transport": "ServerSentEvents","transferFormats": ["Text"]},{"transport": "LongPolling","transferFormats": ["Text", "Binary"]}]
}

2. WebSocket 消息格式

2.1 消息类型枚举

public enum MessageType
{Invocation = 1,        // 方法调用StreamItem = 2,        // 流数据项Completion = 3,       // 完成StreamInvocation = 4,  // 流调用CancelInvocation = 5,  // 取消调用Ping = 6,             // 心跳Pong = 7,             // 心跳响应Close = 8,             // 关闭连接Ack = 9                // 确认
}

2.2 实际消息示例

客户端调用服务器方法
{"protocol": "json","version": 1,"type": 1,  // Invocation"target": "SendMessage","arguments": ["张三", "你好世界"],"invocationId": "12345"
}
服务器调用客户端方法
{"protocol": "json","version": 1,"type": 1,  // Invocation"target": "ReceiveMessage","arguments": ["张三", "你好世界"]
}
心跳消息
{"protocol": "json","version": 1,"type": 6  // Ping
}

3. 长轮询协议

3.1 轮询请求

POST /chathub/poll?connectionId=abc123 HTTP/1.1
Host: localhost:5000
Content-Type: application/json
Connection: keep-alive{"protocol": "json","version": 1
}

3.2 轮询响应

HTTP/1.1 200 OK
Content-Type: application/json
Connection: keep-alive{"messages": [{"protocol": "json","version": 1,"type": 1,"target": "ReceiveMessage","arguments": ["张三", "你好世界"]}]
}

4. 二进制协议 (MessagePack)

4.1 消息结构

[消息类型][消息长度][消息内容]

4.2 序列化示例

// C# 对象
var message = new { User = "张三", Content = "你好" };// MessagePack 序列化后的字节数组
[0x01, 0x00, 0x00, 0x00, 0x1A, 0x82, 0xA4, 0x55, 0x73, 0x65, 0x72, 0xA6, 0xE5, 0xBC, 0xA0, 0xE4, 0xB8, 0x89, 0xA7, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0xA6, 0xE4, 0xBD, 0xA0, 0xE5, 0xA5, 0xBD]

5. 连接管理

5.1 连接状态

public enum ConnectionState
{Disconnected = 0,Connecting = 1,Connected = 2,Reconnecting = 3
}

5.2 连接生命周期

1. 创建连接对象
2. 发起握手请求
3. 选择传输协议
4. 建立连接通道
5. 开始消息交换
6. 处理断开/重连

6. 错误处理

6.1 错误消息格式

{"protocol": "json","version": 1,"type": 3,  // Completion"invocationId": "12345","error": "方法 'SendMessage' 不存在","result": null
}

6.2 常见错误类型

  • 连接错误: 网络中断、服务器不可用
  • 协议错误: 消息格式不正确
  • 方法错误: 调用的方法不存在
  • 参数错误: 参数类型不匹配
  • 授权错误: 没有权限访问方法

7. 性能优化

7.1 消息批处理

{"protocol": "json","version": 1,"type": 1,"target": "ReceiveMessage","arguments": [["用户1", "消息1"],["用户2", "消息2"],["用户3", "消息3"]]
}

7.2 压缩传输

// 启用 GZIP 压缩
services.AddSignalR().AddHubOptions<ChatHub>(options =>{options.EnableDetailedErrors = true;options.MaximumReceiveMessageSize = 32 * 1024;});

8. 安全机制

8.1 身份验证

[Authorize]
public class ChatHub : Hub
{public async Task SendMessage(string message){var user = Context.User.Identity.Name;await Clients.All.SendAsync("ReceiveMessage", user, message);}
}

8.2 授权策略

[Authorize(Policy = "ChatPolicy")]
public class ChatHub : Hub
{// 只有通过授权策略的用户才能访问
}

9. 调试技巧

9.1 启用详细日志

services.AddSignalR().AddHubOptions<ChatHub>(options =>{options.EnableDetailedErrors = true;});

9.2 客户端调试

// 启用详细日志
const connection = new signalR.HubConnectionBuilder().withUrl("/chathub").configureLogging(signalR.LogLevel.Debug).build();

10. 实际应用场景

10.1 聊天应用

  • 实时消息传递
  • 用户状态同步
  • 群组管理

10.2 游戏服务器

  • 实时游戏状态同步
  • 玩家动作广播
  • 游戏事件通知

10.3 IoT 设备

  • 设备状态监控
  • 远程控制指令
  • 数据采集

总结

SignalR 的底层原理可以概括为:

  1. 协议层: WebSocket + 长轮询 + Server-Sent Events
  2. 消息层: JSON/MessagePack 序列化
  3. RPC层: 双向方法调用机制
  4. 传输层: HTTP/WebSocket 协议
  5. 安全层: 身份验证 + 授权策略

这就是为什么 JavaScript 能调用 C# 方法,C# 能调用 JavaScript 函数的根本原理!

http://www.dtcms.com/a/516036.html

相关文章:

  • 在 Linux 系统上安装 Miniconda、安装 Xinference,并设置 Xinference 开机自启动
  • 第一篇:把任意 HTTP API 一键变成 Agent 工具
  • 使用PCIE B210烧写SIM卡
  • 大模型太贵太慢?豆包1.6想打破这个“行业幻觉”
  • 卖酒网站排名阳江 网站建设
  • 唐宇迪2025最新机器学习课件——学习心得(1)
  • python基于卷积神经网络的桥梁裂缝检测系统(django),附可视化界面,源码
  • 网站建设要学什么asp.net做电商网站设计
  • OpenTelemetry日志采集和链路跟踪部署与问题解决文档
  • Rocky 9 单机安装elastic-9.1.5
  • 黑马程序员C++提高编程_3.STL- 常用容器_list容器
  • 免费模板网站word医疗室内设计网站推荐
  • flutter实现web端实现效果
  • 网站建设与管理题目wordpress页面标题标签
  • 在线预览docx、ppt、excel、doc、pdf等文档解决方案
  • !process 命令详解
  • 渗透测试(4):SQL注入示例
  • 三明做网站全球速卖通规则
  • python3编程基础
  • 解决时序违例(四)
  • 容器化安装新玩法:轻量高效一键部署
  • JavaScript函数基础
  • 实木餐桌椅移动网站建设网站建设定制开发
  • 邯郸网站设计价格特色产品推广方案
  • vscode安装、部署和小技巧 记录
  • 简单常见的勒索病毒加密
  • docker基本知识
  • 什么网站服务器好wordpress如何添加目录菜单
  • 12、【Ubuntu】【VSCode】VSCode 断联问题分析:getent 命令(二)
  • RHCSA作业2