@foundbyte/ws-debugger
v1.0.0-alpha.2
Published
FoundByte WebSocket Debugger(uni-app 跨端调试消息连接)
Keywords
Readme
@foundbyte/ws-debugger
调试 WebSocket 连接封装,用于向调试服务端推送调试消息。兼容 uni-app 各端(H5 / 各小程序 / App / HarmonyOS)与纯 Web 项目。
特性
- 按运行时探测选择连接实现:uni 运行时(uni-app 各端:App / 小程序 / H5)走
uni.connectSocket(SocketTask),纯 Web/Node 环境走原生WebSocket,源码与编译产物行为一致,不依赖条件编译 - 连接未初始化时消息自动入队,连接建立后按序补发(队列上限 100,满员挤掉最旧消息)
- 连接失败/断开自动重置,支持后续重连;含连接超时兜底(10s),兼容鸿蒙微信连接挂起场景
- 外部配置注入(启用条件、手机号、连接地址),不依赖具体业务的环境判断与用户信息
- 无
@dcloudio/types等类型依赖,TS 项目可直接消费源码或 es 产物 - workspace 内以源码方式消费(
main指向src/index.ts)
使用
1. 初始化连接(登录成功后调用一次)
import { connection } from '@foundbyte/ws-debugger'
connection.connect({
appKey: 'dsy_xxx',
env: 'test',
enabled: () => import.meta.env.VITE_APP_ENV !== 'prod',
getMobile: () => userInfo.mobile || '',
getUrl: (mobile, appKey, env) =>
`wss://debug.example.com/ws/debug?mobile=${encodeURIComponent(mobile)}&appKey=${encodeURIComponent(appKey)}&env=${encodeURIComponent(env)}`,
})connect 参数(IWsDebuggerOptions)
| 参数 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| appKey | string | 是 | 发送者 appKey,连接级标识,每条消息自动附加 |
| env | string | 是 | 运行环境(如 dev / test / prod),连接级标识,每条消息自动附加;连接建立时作为 REGISTER_SENDER 消息发送 |
| enabled | () => boolean | 是 | 启用条件,返回 true 才建立连接、才推送消息(如:仅开发版/体验版/非生产环境)。connect 与 send 时都会实时调用 |
| getMobile | () => string | 是 | 获取当前用户手机号。返回空字符串则不连接、不推送;未登录阶段返回空串即可 |
| getUrl | (mobile, appKey, env) => string | 是 | 构建 WebSocket 连接地址,参数为上面注入的值 |
未调用 connect 时的 send 不会丢失:消息进入队列,connect 建立连接后按序补发。
销毁连接(退出登录 / 登录态失效时调用)
import { connection } from '@foundbyte/ws-debugger'
connection.destroy()2. 在拦截器中推送请求 / 响应 / 错误
典型用法:在 HTTP 拦截器(axios / uni.request 封装)的三个阶段推送调试信息,用 traceId 配对、携带耗时。
import { connection, type IDebugMessage } from '@foundbyte/ws-debugger'
/** traceId 递增计数,配合时间戳保证同一毫秒内的多次调用也唯一 */
let traceIdSeed = 0
const genTraceId = () => {
traceIdSeed += 1
return `${Date.now().toString(36)}-${traceIdSeed.toString(36)}`
}
// 请求拦截
http.interceptors.request.use((config) => {
const wsTraceId = genTraceId()
const wsRequestTime = Date.now()
connection.send({
type: 'REQUEST',
data: JSON.stringify({
url: config.url,
method: config.method,
requestBody: config.data,
phase: 'request',
traceId: wsTraceId,
requestTime: wsRequestTime,
}),
})
// 把 traceId / requestTime 挂到 config 上,供响应配对
Object.assign(config, { wsTraceId, wsRequestTime })
return config
})
// 响应拦截(成功、业务错误都在这里推送,与请求用同一 traceId 配对)
http.interceptors.response.use((response) => {
connection.send({
type: 'REQUEST',
data: JSON.stringify({
url: response.config.url,
responseBody: response.data,
status: response.status,
phase: 'response',
traceId: response.config.wsTraceId,
duration: Date.now() - response.config.wsRequestTime,
}),
})
return response
})
// 响应拦截(http 错误 / 网络异常)
http.interceptors.response.use(undefined, (error) => {
connection.send({
type: 'ERROR',
data: JSON.stringify({
url: error.config?.url,
status: error.response?.status,
errMsg: error.message,
phase: 'error',
traceId: error.config?.wsTraceId,
duration: Date.now() - error.config?.wsRequestTime,
}),
})
return Promise.reject(error)
})send 参数(IDebugMessage)
| 参数 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| type | 'REGISTER_SENDER' \| 'REGISTER_RECEIVER' \| 'ERROR' \| 'REQUEST' \| 'PING' \| 'PONG' | 是 | 消息类型。业务推送请求/响应用 REQUEST,推送错误用 ERROR;REGISTER_SENDER / REGISTER_RECEIVER 由连接内部使用 |
| data | string | 否 | 消息体,通常为 JSON.stringify 后的调试数据。发送时自动附加 appKey 与 env |
| fromMobile | string | 否 | 来源手机号(一般不需要手动传,服务端按连接归属识别) |
| appKey | string | 否 | 发送者 appKey,连接建立后自动附加,无需手动传 |
| env | string | 否 | 运行环境,连接建立后自动附加,无需手动传 |
send 行为
- 未
connect时消息入队,连接建立后按序补发;队列上限 100,满员挤掉最旧消息 enabled()返回false或getMobile()返回空串时静默丢弃- 连接未打开时入队等待,连接断开后下次
send自动触发重连
参考实现:travel-uni-mobile(core/apis/request.ts + core/store/modules/user.ts)、keyblade-pro(web/src/utils/ws-debugger.ts + web/src/interceptor.ts)。
构建与发布
pnpm build # tsdown 产出 es/(js + d.ts)
pnpm publish:npm # 发布到 npmworkspace 内通过 workspace:^ 引用,直接消费 src/index.ts 源码。
