Skip to content

Commit ec054c7

Browse files
committed
feat(fe): implement SocketTask class for WebSocket management and provide connection methods
1 parent d542d12 commit ec054c7

File tree

1 file changed

+316
-0
lines changed
  • fe/packages/service/src/api/core/network/websocket

1 file changed

+316
-0
lines changed
Lines changed: 316 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,316 @@
1+
import { invokeAPI } from '@/api/common'
2+
import { callback, isFunction } from '@dimina/common'
3+
4+
/**
5+
* https://developers.weixin.qq.com/miniprogram/dev/api/network/websocket/SocketTask.html
6+
* SocketTask 类,用于管理 WebSocket 连接
7+
*/
8+
class SocketTask {
9+
constructor(socketId) {
10+
this.socketId = socketId
11+
this._readyState = 0 // CONNECTING
12+
}
13+
14+
/**
15+
* 通过 WebSocket 连接发送数据
16+
* @param {Object} opts
17+
*/
18+
send(opts = {}) {
19+
const { data, success, fail, complete, ...rest } = opts
20+
21+
const params = {
22+
socketId: this.socketId,
23+
data,
24+
...rest
25+
}
26+
27+
if (isFunction(success)) {
28+
params.success = callback.store(success)
29+
}
30+
if (isFunction(fail)) {
31+
params.fail = callback.store(fail)
32+
}
33+
if (isFunction(complete)) {
34+
params.complete = callback.store(complete)
35+
}
36+
37+
return invokeAPI('sendSocketMessage', params)
38+
}
39+
40+
/**
41+
* 关闭 WebSocket 连接
42+
* @param {Object} opts
43+
*/
44+
close(opts = {}) {
45+
const { code = 1000, reason = '', success, fail, complete, ...rest } = opts
46+
47+
const params = {
48+
socketId: this.socketId,
49+
code,
50+
reason,
51+
...rest
52+
}
53+
54+
if (isFunction(success)) {
55+
params.success = callback.store(success)
56+
}
57+
if (isFunction(fail)) {
58+
params.fail = callback.store(fail)
59+
}
60+
if (isFunction(complete)) {
61+
params.complete = callback.store(complete)
62+
}
63+
64+
return invokeAPI('closeSocket', params)
65+
}
66+
67+
/**
68+
* 监听 WebSocket 连接打开事件
69+
* @param {Function} callback 回调函数
70+
*/
71+
onOpen(callbackFn) {
72+
if (isFunction(callbackFn)) {
73+
return invokeAPI('onSocketOpen', {
74+
socketId: this.socketId,
75+
callback: callback.store(callbackFn, true)
76+
})
77+
}
78+
}
79+
80+
/**
81+
* 取消监听 WebSocket 连接打开事件
82+
* @param {Function} callback 回调函数
83+
*/
84+
offOpen(callbackFn) {
85+
return invokeAPI('offSocketOpen', {
86+
socketId: this.socketId,
87+
callback: callbackFn
88+
})
89+
}
90+
91+
/**
92+
* 监听 WebSocket 接受到服务器的消息事件
93+
* @param {Function} callback 回调函数
94+
*/
95+
onMessage(callbackFn) {
96+
if (isFunction(callbackFn)) {
97+
return invokeAPI('onSocketMessage', {
98+
socketId: this.socketId,
99+
callback: callback.store(callbackFn, true)
100+
})
101+
}
102+
}
103+
104+
/**
105+
* 取消监听 WebSocket 接受到服务器的消息事件
106+
* @param {Function} callback 回调函数
107+
*/
108+
offMessage(callbackFn) {
109+
return invokeAPI('offSocketMessage', {
110+
socketId: this.socketId,
111+
callback: callbackFn
112+
})
113+
}
114+
115+
/**
116+
* 监听 WebSocket 错误事件
117+
* @param {Function} callback 回调函数
118+
*/
119+
onError(callbackFn) {
120+
if (isFunction(callbackFn)) {
121+
return invokeAPI('onSocketError', {
122+
socketId: this.socketId,
123+
callback: callback.store(callbackFn, true)
124+
})
125+
}
126+
}
127+
128+
/**
129+
* 取消监听 WebSocket 错误事件
130+
* @param {Function} callback 回调函数
131+
*/
132+
offError(callbackFn) {
133+
return invokeAPI('offSocketError', {
134+
socketId: this.socketId,
135+
callback: callbackFn
136+
})
137+
}
138+
139+
/**
140+
* 监听 WebSocket 连接关闭事件
141+
* @param {Function} callback 回调函数
142+
*/
143+
onClose(callbackFn) {
144+
if (isFunction(callbackFn)) {
145+
return invokeAPI('onSocketClose', {
146+
socketId: this.socketId,
147+
callback: callback.store(callbackFn, true)
148+
})
149+
}
150+
}
151+
152+
/**
153+
* 取消监听 WebSocket 连接关闭事件
154+
* @param {Function} callback 回调函数
155+
*/
156+
offClose(callbackFn) {
157+
return invokeAPI('offSocketClose', {
158+
socketId: this.socketId,
159+
callback: callbackFn
160+
})
161+
}
162+
163+
/**
164+
* 获取 WebSocket 连接状态
165+
* @returns {number} 连接状态
166+
*/
167+
get readyState() {
168+
return this._readyState
169+
}
170+
171+
/**
172+
* WebSocket 的连接状态常量
173+
*/
174+
static get CONNECTING() { return 0 }
175+
static get OPEN() { return 1 }
176+
static get CLOSING() { return 2 }
177+
static get CLOSED() { return 3 }
178+
}
179+
180+
/**
181+
* 创建一个 WebSocket 连接
182+
* https://developers.weixin.qq.com/miniprogram/dev/api/network/websocket/wx.connectSocket.html
183+
* @param {Object} opts 配置对象
184+
* @param {string} opts.url 开发者服务器 wss 接口地址
185+
* @param {Object} [opts.header] HTTP Header,Header 中不能设置 Referer
186+
* @param {Array<string>} [opts.protocols] 子协议数组
187+
* @param {boolean} [opts.tcpNoDelay=false] 建立 TCP 连接的时候的 TCP_NODELAY 设置
188+
* @param {boolean} [opts.perMessageDeflate=false] 是否开启压缩扩展
189+
* @param {number} [opts.timeout] 超时时间,单位为毫秒
190+
* @param {boolean} [opts.forceCellularNetwork=false] 强制使用蜂窝网络发送请求
191+
* @param {Function} [opts.success] 接口调用成功的回调函数
192+
* @param {Function} [opts.fail] 接口调用失败的回调函数
193+
* @param {Function} [opts.complete] 接口调用结束的回调函数(调用成功、失败都会执行)
194+
* @returns {SocketTask} WebSocket 任务对象
195+
*/
196+
export function connectSocket(opts = {}) {
197+
const {
198+
url,
199+
header = {},
200+
protocols = [],
201+
tcpNoDelay = false,
202+
perMessageDeflate = false,
203+
timeout,
204+
forceCellularNetwork = false,
205+
success,
206+
fail,
207+
complete,
208+
...rest
209+
} = opts
210+
211+
// 验证必填参数
212+
if (!url) {
213+
const error = new Error('url is required')
214+
if (isFunction(fail)) {
215+
fail(error)
216+
}
217+
if (isFunction(complete)) {
218+
complete(error)
219+
}
220+
throw error
221+
}
222+
223+
// 生成唯一的 socket ID
224+
const socketId = `socket_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
225+
226+
// 创建 SocketTask 实例
227+
const socketTask = new SocketTask(socketId)
228+
229+
// 准备参数
230+
const params = {
231+
socketId,
232+
url,
233+
header,
234+
protocols,
235+
tcpNoDelay,
236+
perMessageDeflate,
237+
timeout,
238+
forceCellularNetwork,
239+
...rest
240+
}
241+
242+
if (isFunction(success)) {
243+
params.success = callback.store((res) => {
244+
socketTask._readyState = SocketTask.OPEN
245+
success(res)
246+
})
247+
}
248+
if (isFunction(fail)) {
249+
params.fail = callback.store((error) => {
250+
socketTask._readyState = SocketTask.CLOSED
251+
fail(error)
252+
})
253+
}
254+
if (isFunction(complete)) {
255+
params.complete = callback.store(complete)
256+
}
257+
258+
// 调用底层 API
259+
invokeAPI('connectSocket', params)
260+
261+
return socketTask
262+
}
263+
264+
/**
265+
* 通过 WebSocket 连接发送数据(全局方法,不推荐使用)
266+
* @deprecated 推荐使用 SocketTask 的方式管理 WebSocket 连接
267+
* @param {Object} opts
268+
*/
269+
export function sendSocketMessage(opts) {
270+
return invokeAPI('sendSocketMessage', opts)
271+
}
272+
273+
/**
274+
* 关闭 WebSocket 连接(全局方法,不推荐使用)
275+
* @deprecated 推荐使用 SocketTask 的方式管理 WebSocket 连接
276+
* @param {Object} opts
277+
*/
278+
export function closeSocket(opts) {
279+
return invokeAPI('closeSocket', opts)
280+
}
281+
282+
/**
283+
* 监听 WebSocket 连接打开事件(全局方法,不推荐使用)
284+
* @deprecated 推荐使用 SocketTask 的方式管理 WebSocket 连接
285+
* @param {Function} callback
286+
*/
287+
export function onSocketOpen(callbackFn) {
288+
return invokeAPI('onSocketOpen', { callback: callback.store(callbackFn, true) })
289+
}
290+
291+
/**
292+
* 监听 WebSocket 接受到服务器的消息事件(全局方法,不推荐使用)
293+
* @deprecated 推荐使用 SocketTask 的方式管理 WebSocket 连接
294+
* @param {Function} callback
295+
*/
296+
export function onSocketMessage(callbackFn) {
297+
return invokeAPI('onSocketMessage', { callback: callback.store(callbackFn, true) })
298+
}
299+
300+
/**
301+
* 监听 WebSocket 错误事件(全局方法,不推荐使用)
302+
* @deprecated 推荐使用 SocketTask 的方式管理 WebSocket 连接
303+
* @param {Function} callback
304+
*/
305+
export function onSocketError(callbackFn) {
306+
return invokeAPI('onSocketError', { callback: callback.store(callbackFn, true) })
307+
}
308+
309+
/**
310+
* 监听 WebSocket 连接关闭事件(全局方法,不推荐使用)
311+
* @deprecated 推荐使用 SocketTask 的方式管理 WebSocket 连接
312+
* @param {Function} callback
313+
*/
314+
export function onSocketClose(callbackFn) {
315+
return invokeAPI('onSocketClose', { callback: callback.store(callbackFn, true) })
316+
}

0 commit comments

Comments
 (0)