SocketCluster协议深度解析:从握手到认证的全流程指南

SocketCluster协议深度解析:从握手到认证的全流程指南

socketcluster Highly scalable realtime pub/sub and RPC framework socketcluster 项目地址: https://gitcode.com/gh_mirrors/so/socketcluster

协议概述

SocketCluster协议构建于WebSocket协议之上,是一个完整的实时通信解决方案。该协议采用分层设计,各层功能明确且相互独立,开发者可以根据需求灵活选择实现部分或全部功能模块。

核心组件

  1. 握手层(Handshake):建立连接后的第一个必经步骤
  2. 连接健康检查(Ping/Pong):维持长连接的可靠性机制
  3. 事件层(Event Layer):基础的点对点通信能力
  4. 发布订阅层(Pub/Sub):一对多的消息广播机制
  5. 认证层(Authentication):安全认证体系

对于基础客户端实现,必须包含握手、心跳检测和基本事件处理能力,而发布订阅和认证功能则属于可选模块。

协议版本演进

V1与V2的主要差异

  1. 版本支持

    • V14及以下版本仅支持V1协议
    • V15及以上版本默认使用V2协议,同时兼容V1
  2. 握手响应

    • V1仅在包含cid时返回响应
    • V2始终返回响应,无cid时省略rid
  3. 心跳机制

    • V1使用"#1"和"#2"作为ping/pong标识
    • V2使用空字符串""作为标识
  4. 事件命名空间

    • V1中所有#开头的事件均为保留事件
    • V2仅特定#开头事件为保留事件

关键概念详解

调用ID与响应ID

cid(Call ID)和rid(Response ID)构成了SocketCluster的请求-响应追踪机制:

  • cid必须保证在连接生命周期内全局唯一
  • 服务端和客户端的cid属于不同命名空间
  • 推荐使用自增数字而非UUID以提高效率

保留事件列表

V1协议:

所有以#开头的事件名称

V2协议:
  • #handshake(握手)
  • #publish(发布)
  • #subscribe(订阅)
  • #unsubscribe(取消订阅)
  • #kickOut(强制踢出)
  • #authenticate(认证)
  • #setAuthToken(令牌设置)
  • #removeAuthToken(令牌移除)

握手流程详解

握手是建立连接后的第一个必要步骤,客户端在完成WebSocket连接后必须立即发送握手事件。

握手事件结构

{
  "event": "#handshake",
  "data": {
    "authToken": "JWT_TOKEN" // 可选认证令牌
  },
  "cid": 1 // 可选调用ID
}

握手响应分析

成功响应示例:

{
  "rid": 1,
  "data": {
    "id": "CONNECTION_ID",
    "pingTimeout": 20000,
    "isAuthenticated": false
  }
}

版本差异说明:

  • V14及以下:仅当包含cid时返回响应
  • V15及以上:始终返回响应,无cid时省略rid

连接健康监测机制

心跳检测实现

| 协议版本 | Ping消息 | Pong响应 | |---------|---------|---------| | V1 | "#1" | "#2" | | V2 | "" | "" |

心跳机制用于检测网络异常断开等场景,是维持长连接可靠性的关键设计。

事件层架构解析

基础事件传输

// 发送事件
socket.transmit('eventName', data)

// 接收事件
for await (const data of socket.receiver('eventName')) {
  console.log(data)
}

事件数据结构:

{
  "event": "customEvent",
  "data": {} // 可选数据载荷
}

远程过程调用(RPC)

// 发起调用
const result = await socket.invoke('getUser', {id: 123})

// 处理调用
for await (const req of socket.procedure('getUser')) {
  req.end(await getUser(req.data.id))
}

RPC请求结构:

{
  "cid": 123,
  "event": "getUser",
  "data": {"id": 123}
}

成功响应:

{"rid": 123, "data": {}}

失败响应:

{
  "rid": 123,
  "error": {
    "message": "调用被中间件拦截",
    "name": "MiddlewareBlockedError"
  }
}

发布订阅系统详解

订阅流程

const channel = socket.subscribe('news')
for await (const msg of channel) {
  console.log(msg)
}

订阅请求:

{
  "event": "#subscribe",
  "data": {"channel": "news"},
  "cid": 123
}

发布机制

// 无需确认的发布
socket.transmitPublish('news', update)

// 需要确认的发布
await socket.invokePublish('news', update)

发布请求:

{
  "event": "#publish",
  "data": {
    "channel": "news",
    "data": {} // 消息内容
  },
  "cid": 123 // 可选
}

强制取消订阅

服务端可通过kickOut方法强制客户端退订:

socket.kickOut('news', '违规操作')

客户端接收的踢出事件:

{
  "event": "#kickOut",
  "data": {
    "channel": "news",
    "message": "违规操作"
  }
}

认证系统实现方案

令牌获取流程

服务端设置令牌:

socket.setAuthToken({userId: 123})

客户端接收的令牌事件:

{
  "event": "#setAuthToken",
  "data": {
    "token": "JWT_TOKEN"
  }
}

认证方式选择

  1. 握手时认证
{
  "event": "#handshake",
  "data": {
    "authToken": "JWT_TOKEN"
  }
}
  1. 独立认证事件
{
  "event": "#authenticate",
  "data": {
    "authToken": "JWT_TOKEN"
  },
  "cid": 123
}

认证响应:

{
  "rid": 123,
  "data": {
    "isAuthenticated": true
  }
}

最佳实践建议

  1. CID生成策略:推荐使用自增数字而非UUID
  2. 错误处理:始终处理可能的TimeoutError
  3. 协议选择:新项目建议直接使用V2协议
  4. 心跳间隔:根据实际网络环境调整pingTimeout
  5. 认证优化:优先采用握手时认证减少往返

通过深入理解SocketCluster协议各层的设计原理和实现细节,开发者可以构建出高效可靠的实时应用系统。该协议的分层设计既保证了核心功能的稳定性,又为不同场景下的定制化需求提供了灵活空间。

socketcluster Highly scalable realtime pub/sub and RPC framework socketcluster 项目地址: https://gitcode.com/gh_mirrors/so/socketcluster

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

姚婕妹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值