118 lines
2.9 KiB
Markdown
118 lines
2.9 KiB
Markdown
# WSS 协议要点
|
||
|
||
本文件记录 Go 版本当前实现依据,来源包括浏览器手动抢购 HAR、软件运行 HAR/日志、逆向导出的分析文本,以及 Python 参考项目 `/Users/yml/codes/douyu_login_py/core/huya`。
|
||
|
||
## 连接
|
||
|
||
- WebSocket URL:`wss://<host>/?baseinfo=<base64 taf>`
|
||
- 默认 host:`77bc035c-ws.va.huya.com`
|
||
- host 来自 `launch.queryHttpDns` 或浏览器抓包,不应长期写死。
|
||
- 握手启用 `permessage-deflate`。
|
||
- Go 版本使用 `github.com/gorilla/websocket` 处理握手、mask 与压缩。
|
||
|
||
`baseinfo` 是 `WSConnectParaInfo` 的 TAF 编码后 base64,再 URL escape。WSS 模式会把 Cookie 中的 `huya_ua` 归一为:
|
||
|
||
```text
|
||
webh5&0.0.1&websocket&&diypc_52775
|
||
```
|
||
|
||
## 外层消息
|
||
|
||
Python 参考中对应 `WssMessage/WssCommand`,Go 版本实现为 `internal/huya/wss_message.go`。
|
||
|
||
```text
|
||
1B version(0) + 1B command + 4B sequence(big-endian) + body
|
||
```
|
||
|
||
已知命令:
|
||
|
||
- `0x03`:RPC request
|
||
- `0x04`:RPC response
|
||
- `0x10`:heartbeat send
|
||
- `0x11`:heartbeat recv
|
||
- `0x17`:confirm
|
||
- `0x21`:register
|
||
|
||
已知 sequence:
|
||
|
||
- 心跳:`0x1d00000d`
|
||
- `launch.wsLaunch`:`0x1d000078`
|
||
- `mobileui.getConfig`:`0x1d000076`
|
||
- register:`0x1d00003c`
|
||
- confirm:`0x1d000002`
|
||
- 业务 RPC:`0x1d000106`
|
||
|
||
## RPC body
|
||
|
||
WUP 请求由 `internal/wup` 编码,输出自带 4 字节大端总长度。
|
||
|
||
小包格式:
|
||
|
||
```text
|
||
[4B WUP 总长度][WUP body] + 2c 36 00 4c 5c 66 00
|
||
```
|
||
|
||
大包格式:
|
||
|
||
```text
|
||
[1B 长度低字节][4B WUP 总长度][裸 WUP body] + trace 尾部
|
||
```
|
||
|
||
其中 trace 尾部形如:
|
||
|
||
```text
|
||
,6%<hex16>:<hex16>:0:3 + 4c 5c 66 00
|
||
```
|
||
|
||
响应解析时,Go 版本会从 WSS body 中切出内部 WUP 包,再交给 `wup.Response.Decode`。
|
||
|
||
## 初始化流程
|
||
|
||
WSS session 建立后按以下顺序初始化:
|
||
|
||
1. 发送心跳。
|
||
2. 调用 `launch.wsLaunch`,读取 `guid` 和 `clientIp`。
|
||
3. 调用 `mobileui.getConfig`,失败只记录日志,继续后续流程。
|
||
4. 使用 `wsLaunch` 返回的 `guid` 发送 register。
|
||
5. 发送 confirm。
|
||
|
||
之后业务接口复用同一个连接,并用 FIFO 队列匹配 `0x04` RPC response。
|
||
|
||
## 活动接口
|
||
|
||
当前 Go 版本的 HTTP 与 WSS 都实现 `huya.ActivityClient`:
|
||
|
||
- `webActUI.getActPrizeList`
|
||
- `webActUI.getUserScore`
|
||
- `webActUI.getUserPrizeRecords`
|
||
- `webActUI.scoreExchangePrize`
|
||
|
||
抢购兑换请求结构:
|
||
|
||
```text
|
||
tReq.user
|
||
tReq.sid
|
||
tReq.pid
|
||
tReq.ip = ""
|
||
tReq.clientEnv = {}
|
||
tReq.source = ""
|
||
tReq.isRole = 1
|
||
```
|
||
|
||
浏览器手动抢购小黄鸭成功回包确认:
|
||
|
||
- `webActUI.scoreExchangePrize`
|
||
- `sid=2203`
|
||
- `pid=12889`
|
||
- `status=200`
|
||
- `msg=请求成功`
|
||
- `exchangeInfo.pid=12889`
|
||
- `exchangeInfo.exchangeScore=988`
|
||
- `exchangeInfo.desc=兑换奖品:套装-潮萌小黄鸭`
|
||
|
||
## 待完善
|
||
|
||
- 自动调用 `launch.queryHttpDns` 获取最新 WSS host。
|
||
- 对 WSS RPC response 做 request id 或业务包级匹配,当前与 Python 参考一致使用 FIFO。
|
||
- 增加基于真实抓包样本的 WSS body 编解码单测。
|