|
@@ -2,10 +2,13 @@ import { ReadyStateCallback, RequestCallback } from './types/callback';
|
2
|
2
|
import { Packet } from './packet';
|
3
|
3
|
import { Utils } from './utils';
|
4
|
4
|
|
|
5
|
+/**
|
|
6
|
+ * 数据包默认最大发送的数据量大小
|
|
7
|
+ */
|
5
|
8
|
const MAX_PAYLOAD = 1024 * 1024;
|
6
|
9
|
|
7
|
10
|
/**
|
8
|
|
- * Client ws client, 单例模式, 负责维护连接
|
|
11
|
+ * 初始化链接以及收发数据
|
9
|
12
|
*/
|
10
|
13
|
class Client {
|
11
|
14
|
private _maxPayload: number;
|
|
@@ -18,6 +21,11 @@ class Client {
|
18
|
21
|
private socket: WebSocket;
|
19
|
22
|
private readyStateCallback: ReadyStateCallback;
|
20
|
23
|
|
|
24
|
+ /**
|
|
25
|
+ * 构造函数,初始化客户端链接
|
|
26
|
+ * @param url websocket链接地址
|
|
27
|
+ * @param readyStateCallback 链接状态回调,可以处理onOpen、onClose、onError
|
|
28
|
+ */
|
21
|
29
|
constructor(url: string, readyStateCallback: ReadyStateCallback) {
|
22
|
30
|
this.listeners = new Map<number, (data: string) => void>();
|
23
|
31
|
this.requestHeader = '';
|
|
@@ -29,7 +37,11 @@ class Client {
|
29
|
37
|
this.socket = this.connect();
|
30
|
38
|
}
|
31
|
39
|
|
32
|
|
- // 向服务端发送ping包保持长连接
|
|
40
|
+ /**
|
|
41
|
+ * 发送ping请求,来保持长连接
|
|
42
|
+ * @param param 请求参数,比如{"hello":"world"}
|
|
43
|
+ * @param requestCallback 请求状态回调
|
|
44
|
+ */
|
33
|
45
|
public ping(param: any, requestCallback: RequestCallback) {
|
34
|
46
|
if (this.socket.readyState !== this.socket.OPEN) {
|
35
|
47
|
throw new Error('asyncSend: connection refuse');
|
|
@@ -59,10 +71,10 @@ class Client {
|
59
|
71
|
}
|
60
|
72
|
|
61
|
73
|
/**
|
62
|
|
- * asyncSend
|
63
|
|
- * @param {*} operator
|
64
|
|
- * @param {*} param
|
65
|
|
- * @param {*} callback 仅此次有效的callback
|
|
74
|
+ * 异步向服务端发送请求
|
|
75
|
+ * @param operator 路由地址
|
|
76
|
+ * @param param 请求参数,比如{"hello":"world"}
|
|
77
|
+ * @param callback 请求状态回调处理
|
66
|
78
|
*/
|
67
|
79
|
public asyncSend(operator: string, param: any, callback: RequestCallback) {
|
68
|
80
|
console.info('websocket send data', operator, this.requestHeader, param);
|
|
@@ -100,7 +112,12 @@ class Client {
|
100
|
112
|
);
|
101
|
113
|
}
|
102
|
114
|
|
103
|
|
- // 同步请求服务端数据
|
|
115
|
+ /**
|
|
116
|
+ * 同步方式向服务端发送请求
|
|
117
|
+ * @param operator 路由地址
|
|
118
|
+ * @param param 请求参数,比如{"hello":"world"}
|
|
119
|
+ * @param callback 请求状态回调处理
|
|
120
|
+ */
|
104
|
121
|
public async syncSend(
|
105
|
122
|
operator: string,
|
106
|
123
|
param: any,
|
|
@@ -109,34 +126,55 @@ class Client {
|
109
|
126
|
await this.asyncSend(operator, param, callback);
|
110
|
127
|
}
|
111
|
128
|
|
112
|
|
- // 添加消息监听
|
|
129
|
+ /**
|
|
130
|
+ * 添加消息监听
|
|
131
|
+ * @description 添加消息监听器,比如operator是/v1/message/listener,那么从服务端推送到/v1/message/listener的消息会进入到定义的listener里面进行处理
|
|
132
|
+ * @param operator 消息监听地址
|
|
133
|
+ * @param listener 定义如何处理从服务端返回的消息
|
|
134
|
+ */
|
113
|
135
|
public addMessageListener(
|
114
|
136
|
operator: string,
|
115
|
137
|
listener: (data: string) => void,
|
116
|
|
- ) {
|
|
138
|
+ ): void {
|
117
|
139
|
this.listeners[Utils.crc32(operator)] = listener;
|
118
|
140
|
}
|
119
|
141
|
|
120
|
|
- // 移除消息监听
|
|
142
|
+ /**
|
|
143
|
+ * 移除消息监听
|
|
144
|
+ * @param operator 消息监听地址
|
|
145
|
+ */
|
121
|
146
|
public removeMessageListener(operator: string) {
|
122
|
147
|
delete this.listeners[Utils.crc32(operator)];
|
123
|
148
|
}
|
124
|
149
|
|
125
|
|
- // 获取socket的链接状态
|
|
150
|
+ /**
|
|
151
|
+ * 返回Websocket链接状态
|
|
152
|
+ * @returns Websocket的链接状态
|
|
153
|
+ */
|
126
|
154
|
public get readyState(): number {
|
127
|
155
|
return this.socket.readyState;
|
128
|
156
|
}
|
129
|
157
|
|
130
|
|
- // 设置单个请求能够处理的最大字节数
|
|
158
|
+ /**
|
|
159
|
+ * 设置可以处理的数据包上限
|
|
160
|
+ * @param maxPayload 最多可以处理的数据包大小
|
|
161
|
+ */
|
131
|
162
|
public set maxPayload(maxPayload: number) {
|
132
|
163
|
this._maxPayload = maxPayload;
|
133
|
164
|
}
|
134
|
165
|
|
|
166
|
+ /**
|
|
167
|
+ * 获取可以处理的数据包大小
|
|
168
|
+ */
|
135
|
169
|
public get maxPayload(): number {
|
136
|
170
|
return this._maxPayload;
|
137
|
171
|
}
|
138
|
172
|
|
139
|
|
- // 设置请求属性
|
|
173
|
+ /**
|
|
174
|
+ * 添加请求属性,会携带在数据帧里面发送到服务端
|
|
175
|
+ * @param key 属性名
|
|
176
|
+ * @param value 属性值
|
|
177
|
+ */
|
140
|
178
|
public setRequestProperty(key: string, value: string) {
|
141
|
179
|
let v = this.getRequestProperty(key);
|
142
|
180
|
|
|
@@ -144,7 +182,10 @@ class Client {
|
144
|
182
|
this.requestHeader = this.requestHeader + key + '=' + value + ';';
|
145
|
183
|
}
|
146
|
184
|
|
147
|
|
- // 获取请求属性
|
|
185
|
+ /**
|
|
186
|
+ * 获取请求属性
|
|
187
|
+ * @param key 属性名
|
|
188
|
+ */
|
148
|
189
|
public getRequestProperty(key: string): string {
|
149
|
190
|
if (this.requestHeader !== undefined) {
|
150
|
191
|
let values = this.requestHeader.split(';');
|
|
@@ -159,7 +200,11 @@ class Client {
|
159
|
200
|
return '';
|
160
|
201
|
}
|
161
|
202
|
|
162
|
|
- // 设置Response属性
|
|
203
|
+ /**
|
|
204
|
+ * 设置响应属性,客户端基本用不到,都是服务端来进行设置
|
|
205
|
+ * @param key 属性名
|
|
206
|
+ * @param value 属性值
|
|
207
|
+ */
|
163
|
208
|
public setResponseProperty(key: string, value: string) {
|
164
|
209
|
let v = this.getResponseProperty(key);
|
165
|
210
|
|
|
@@ -167,7 +212,10 @@ class Client {
|
167
|
212
|
this.responseHeader = this.responseHeader + key + '=' + value + ';';
|
168
|
213
|
}
|
169
|
214
|
|
170
|
|
- // 获取响应属性
|
|
215
|
+ /**
|
|
216
|
+ * 获取从服务端返回的属性
|
|
217
|
+ * @param key 获取响应属性
|
|
218
|
+ */
|
171
|
219
|
public getResponseProperty(key: string): string {
|
172
|
220
|
if (this.responseHeader !== undefined) {
|
173
|
221
|
let values = this.responseHeader.split(';');
|
|
@@ -182,7 +230,9 @@ class Client {
|
182
|
230
|
return '';
|
183
|
231
|
}
|
184
|
232
|
|
185
|
|
- // 创建连接
|
|
233
|
+ /**
|
|
234
|
+ * 创建websocket链接
|
|
235
|
+ */
|
186
|
236
|
private connect(): WebSocket {
|
187
|
237
|
const readyStateCallback = this.readyStateCallback;
|
188
|
238
|
let ws = new WebSocket(this.url);
|
|
@@ -245,6 +295,9 @@ class Client {
|
245
|
295
|
return ws;
|
246
|
296
|
}
|
247
|
297
|
|
|
298
|
+ /**
|
|
299
|
+ * 断线重连
|
|
300
|
+ */
|
248
|
301
|
private reconnect() {
|
249
|
302
|
if (!this.reconnectLock) {
|
250
|
303
|
this.reconnectLock = true;
|
|
@@ -258,6 +311,10 @@ class Client {
|
258
|
311
|
}
|
259
|
312
|
}
|
260
|
313
|
|
|
314
|
+ /**
|
|
315
|
+ * 向服务端发送数据请求
|
|
316
|
+ * @param data 向服务端传送的数据
|
|
317
|
+ */
|
261
|
318
|
private send(data: ArrayBuffer) {
|
262
|
319
|
if (this.socket.readyState !== this.socket.OPEN) {
|
263
|
320
|
console.error('WebSocket is already in CLOSING or CLOSED state.');
|