Browse Source

chore: update ts-sdk

wxyyxc1992 5 years ago
parent
commit
a6c28c9a2f
3 changed files with 229 additions and 146 deletions
  1. 36
    53
      packages/cts-core/example/index.ts
  2. 167
    93
      packages/cts-core/src/client.ts
  3. 26
    0
      packages/cts-core/src/error.ts

+ 36
- 53
packages/cts-core/example/index.ts View File

@@ -1,61 +1,44 @@
1 1
 import { Client } from '../src/client';
2
+import { WebsocketError } from './error';
2 3
 
3 4
 const url = 'ws://127.0.0.1:8081';
4
-const client = new Client(
5
-  url,
6
-  new (class {
7
-    public onOpen(): void {
8
-      client.ping(
9
-        {},
10
-        new (class {
11
-          public onStart(): void {
12
-            console.log('start ping');
13
-          }
14
-
15
-          public onSuccess(data: string): void {
16
-            console.log('ping successful:', data);
17
-          }
18
-
19
-          public onError(code: number, message: string): void {
20
-            console.log('ping error:', message);
21
-          }
22
-
23
-          public onEnd(): void {
24
-            console.log('end ping');
25
-          }
26
-        })()
5
+const client = new Client(url, {
6
+  onOpen(): void {
7
+    client
8
+      .ping({})
9
+      .then(
10
+        (res: string): void => {
11
+          console.log('ping sucessful:', res);
12
+        },
13
+      )
14
+      .catch(
15
+        (reason: WebsocketError): void => {
16
+          console.log('ping error:', reason.code, reason.msg);
17
+        },
27 18
       );
28 19
 
29
-      client.syncSend(
30
-        '/v1/healthy',
31
-        {},
32
-        new (class {
33
-          public onStart(): void {
34
-            console.log('start request');
35
-          }
36
-
37
-          public onSuccess(data: string): void {
38
-            console.log('request successful:', data);
39
-          }
40
-
41
-          public onError(code: number, message: string): void {
42
-            console.log('request error:', message);
43
-          }
44
-
45
-          public onEnd(): void {
46
-            console.log('end request');
47
-          }
48
-        })()
20
+    client
21
+      .request('/v1/healthy', {})
22
+      .then(
23
+        (res: string): void => {
24
+          console.log('request successful:', res);
25
+        },
26
+      )
27
+      .catch(
28
+        (reason: WebsocketError): void => {
29
+          console.log('request error:', reason.code, reason.msg);
30
+        },
49 31
       );
50
-    }
32
+  },
33
+
34
+  onClose(ev: Event): void {
35
+    console.log('connection error', ev);
36
+    console.log(ev);
37
+  },
51 38
 
52
-    public onClose(ev: Event): void {
53
-      console.log('connection error', ev);
54
-      console.log(ev);
55
-    }
39
+  onError(): void {
40
+    console.log('close connection');
41
+  },
42
+});
56 43
 
57
-    public onError(): void {
58
-      console.log('close connection');
59
-    }
60
-  })()
61
-);
44
+client.enableLogger = true;

+ 167
- 93
packages/cts-core/src/client.ts View File

@@ -1,12 +1,16 @@
1 1
 import { Packet } from './packet';
2 2
 import { Utils } from './utils';
3
-import { ReadyStateCallback, RequestCallback } from './types/callback';
3
+import { ReadyStateCallback } from './types/callback';
4
+import { WebsocketError } from './error';
5
+
6
+const clientError = 400;
4 7
 
5 8
 /**
6 9
  * 初始化链接以及收发数据
7 10
  */
8 11
 class Client {
9 12
   private _maxPayload: number;
13
+  private _enableLogger: boolean;
10 14
   private listeners: Map<number, (data: string) => void>;
11 15
   private requestHeader: string;
12 16
   private responseHeader: string;
@@ -29,89 +33,93 @@ class Client {
29 33
     this.url = url;
30 34
     this.reconnectTimes = 0;
31 35
     this.readyStateCallback = readyStateCallback;
36
+    this._enableLogger = false;
32 37
     this.socket = this.connect();
33 38
   }
34 39
 
35 40
   /**
36
-   * 发送ping请求,来保持长连接
37
-   * @param param 请求参数,比如{"hello":"world"}
38
-   * @param requestCallback 请求状态回调
41
+   * 设置可以处理的数据包上限
42
+   * @param maxPayload 最多可以处理的数据包大小
39 43
    */
40
-  public ping(param: object, requestCallback: RequestCallback): void {
41
-    if (this.socket.readyState !== this.socket.OPEN) {
42
-      throw new Error('asyncSend: connection refuse');
43
-    }
44
-
45
-    const heartbeatOperator = 0;
46
-
47
-    this.listeners.set(
48
-      heartbeatOperator,
49
-      (data: string): void => {
50
-        const code = this.getResponseProperty('code');
51
-        if (code !== '') {
52
-          const message = this.getResponseProperty('message');
53
-          requestCallback.onError(Number(code), message);
54
-        } else {
55
-          requestCallback.onSuccess(data);
56
-        }
44
+  public set maxPayload(maxPayload: number) {
45
+    this._maxPayload = maxPayload;
46
+  }
57 47
 
58
-        requestCallback.onEnd();
59
-      },
60
-    );
48
+  /**
49
+   * 获取可以处理的数据包大小
50
+   */
51
+  public get maxPayload(): number {
52
+    return this._maxPayload;
53
+  }
61 54
 
62
-    const p = new Packet();
63
-    this.send(
64
-      p.pack(heartbeatOperator, 0, this.requestHeader, JSON.stringify(param)),
65
-    );
55
+  /**
56
+   * 设置是否允许显示运行日志
57
+   */
58
+  public set enableLogger(enableLogger: boolean) {
59
+    this._enableLogger = enableLogger;
66 60
   }
67 61
 
68 62
   /**
69
-   * 异步向服务端发送请求
70
-   * @param operator 路由地址
71
-   * @param param 请求参数,比如{"hello":"world"}
72
-   * @param callback 请求状态回调处理
63
+   * 获取是否显示日志的配置信息
73 64
    */
74
-  public asyncSend(
75
-    operator: string,
76
-    param: object,
77
-    callback: RequestCallback,
78
-  ): void {
79
-    console.info('websocket send data', operator, this.requestHeader, param);
65
+  public get enableLogger(): boolean {
66
+    return this._enableLogger;
67
+  }
80 68
 
81
-    if (this.socket.readyState !== this.socket.OPEN) {
82
-      throw new Error('asyncSend: connection refuse');
83
-    }
69
+  /**
70
+   * 发送ping请求,来保持长连接
71
+   * @param param 请求参数,比如{"hello":"world"}
72
+   */
73
+  public async ping(param: object): Promise<string> {
74
+    return new Promise(
75
+      (
76
+        resolve: (data: string) => void,
77
+        reject: (err: WebsocketError) => void,
78
+      ): void => {
79
+        if (this.socket.readyState !== this.socket.OPEN) {
80
+          if (this._enableLogger) {
81
+            console.log('[ping]: connection refuse');
82
+          }
84 83
 
85
-    callback.onStart();
86
-
87
-    const sequence = new Date().getTime();
88
-    const listener = Utils.crc32(operator) + sequence;
89
-    this.listeners.set(
90
-      listener,
91
-      (data: string): void => {
92
-        const code = this.getResponseProperty('code');
93
-        if (code !== '') {
94
-          const message = this.getResponseProperty('message');
95
-          callback.onError(Number(code), message);
96
-        } else {
97
-          callback.onSuccess(data);
84
+          reject(new WebsocketError(clientError, 'connection refuse'));
98 85
         }
99 86
 
100
-        callback.onEnd();
101
-
102
-        delete this.listeners[listener];
87
+        const heartbeatOperator = 0;
88
+
89
+        this.listeners.set(
90
+          heartbeatOperator,
91
+          (data: string): void => {
92
+            const code = this.getResponseProperty('code');
93
+            if (code !== '') {
94
+              const message = this.getResponseProperty('message');
95
+              reject(new WebsocketError(Number(code), message));
96
+            } else {
97
+              resolve(data);
98
+            }
99
+          },
100
+        );
101
+
102
+        const p = new Packet();
103
+        this.send(
104
+          p.pack(
105
+            heartbeatOperator,
106
+            0,
107
+            this.requestHeader,
108
+            JSON.stringify(param),
109
+          ),
110
+        );
111
+
112
+        if (this._enableLogger) {
113
+          console.info(
114
+            '[send data packet]',
115
+            heartbeatOperator,
116
+            0,
117
+            this.requestHeader,
118
+            param,
119
+          );
120
+        }
103 121
       },
104 122
     );
105
-
106
-    const p = new Packet();
107
-    this.send(
108
-      p.pack(
109
-        Utils.crc32(operator),
110
-        sequence,
111
-        this.requestHeader,
112
-        JSON.stringify(param),
113
-      ),
114
-    );
115 123
   }
116 124
 
117 125
   /**
@@ -120,12 +128,8 @@ class Client {
120 128
    * @param param 请求参数,比如{"hello":"world"}
121 129
    * @param callback 请求状态回调处理
122 130
    */
123
-  public async syncSend(
124
-    operator: string,
125
-    param: object,
126
-    callback: RequestCallback,
127
-  ): Promise<void> {
128
-    await this.asyncSend(operator, param, callback);
131
+  public async request(operator: string, param: object): Promise<string> {
132
+    return await this.asyncSend(operator, param);
129 133
   }
130 134
 
131 135
   /**
@@ -157,21 +161,6 @@ class Client {
157 161
     return this.socket.readyState;
158 162
   }
159 163
 
160
-  /**
161
-   * 设置可以处理的数据包上限
162
-   * @param maxPayload 最多可以处理的数据包大小
163
-   */
164
-  public set maxPayload(maxPayload: number) {
165
-    this._maxPayload = maxPayload;
166
-  }
167
-
168
-  /**
169
-   * 获取可以处理的数据包大小
170
-   */
171
-  public get maxPayload(): number {
172
-    return this._maxPayload;
173
-  }
174
-
175 164
   /**
176 165
    * 添加请求属性,会携带在数据帧里面发送到服务端
177 166
    * @param key 属性名
@@ -242,18 +231,30 @@ class Client {
242 231
     ws.binaryType = 'blob';
243 232
 
244 233
     ws.onopen = (ev): void => {
234
+      if (this._enableLogger) {
235
+        console.info('[websocket] open connection');
236
+      }
237
+
245 238
       this.reconnectTimes = 0;
246 239
 
247 240
       readyStateCallback.onOpen(ev);
248 241
     };
249 242
 
250 243
     ws.onclose = (ev): void => {
244
+      if (this._enableLogger) {
245
+        console.info('[websocket] close connection');
246
+      }
247
+
251 248
       this.reconnect();
252 249
 
253 250
       readyStateCallback.onClose(ev);
254 251
     };
255 252
 
256 253
     ws.onerror = (ev): void => {
254
+      if (this._enableLogger) {
255
+        console.info('[websocket] error');
256
+      }
257
+
257 258
       this.reconnect();
258 259
 
259 260
       readyStateCallback.onError(ev);
@@ -284,8 +285,10 @@ class Client {
284 285
               );
285 286
             }
286 287
 
287
-            if (operator !== 0 && packet.body !== 'null') {
288
-              console.info('receive data', packet.body);
288
+            if (this._enableLogger) {
289
+              if (operator !== 0 && packet.body !== 'null') {
290
+                console.info('receive data packet', packet.body);
291
+              }
289 292
             }
290 293
           } catch (e) {
291 294
             throw new Error(e);
@@ -305,7 +308,10 @@ class Client {
305 308
   private reconnect(): void {
306 309
     if (!this.reconnectLock) {
307 310
       this.reconnectLock = true;
308
-      console.info('websocket reconnect in ' + this.reconnectTimes + 's');
311
+      if (this._enableLogger) {
312
+        console.info('websocket reconnect in ' + this.reconnectTimes + 's');
313
+      }
314
+
309 315
       // 尝试重连
310 316
       setTimeout((): void => {
311 317
         this.reconnectTimes++;
@@ -321,15 +327,83 @@ class Client {
321 327
    */
322 328
   private send(data: ArrayBuffer): void {
323 329
     if (this.socket.readyState !== this.socket.OPEN) {
324
-      console.error('WebSocket is already in CLOSING or CLOSED state.');
330
+      if (this._enableLogger) {
331
+        console.error(
332
+          '[send] WebSocket is already in CLOSING or CLOSED state.',
333
+        );
334
+      }
335
+
325 336
       return;
326 337
     }
338
+
327 339
     try {
328 340
       this.socket.send(data);
329 341
     } catch (e) {
330
-      console.log('send data error', e);
342
+      throw new Error('send data error' + e);
331 343
     }
332 344
   }
345
+
346
+  /**
347
+   * 异步向服务端发送请求
348
+   * @param operator 路由地址
349
+   * @param param 请求参数,比如{"hello":"world"}
350
+   * @param callback 请求状态回调处理
351
+   */
352
+  private asyncSend(operator: string, param: object): Promise<string> {
353
+    return new Promise(
354
+      (
355
+        resolve: (data: string) => void,
356
+        reject: (err: WebsocketError) => void,
357
+      ): void => {
358
+        if (this.socket.readyState !== this.socket.OPEN) {
359
+          if (this._enableLogger) {
360
+            console.log('[ping]: connection refuse');
361
+          }
362
+
363
+          reject(
364
+            new WebsocketError(clientError, 'asyncSend: connection refuse'),
365
+          );
366
+        }
367
+
368
+        const sequence = new Date().getTime();
369
+        const listener = Utils.crc32(operator) + sequence;
370
+        this.listeners.set(
371
+          listener,
372
+          (data: string): void => {
373
+            const code = this.getResponseProperty('code');
374
+            if (code !== '') {
375
+              const message = this.getResponseProperty('message');
376
+              reject(new WebsocketError(Number(code), message));
377
+            } else {
378
+              resolve(data);
379
+            }
380
+
381
+            delete this.listeners[listener];
382
+          },
383
+        );
384
+
385
+        const p = new Packet();
386
+        this.send(
387
+          p.pack(
388
+            Utils.crc32(operator),
389
+            sequence,
390
+            this.requestHeader,
391
+            JSON.stringify(param),
392
+          ),
393
+        );
394
+
395
+        if (this._enableLogger) {
396
+          console.info(
397
+            '[send data packet]',
398
+            operator,
399
+            sequence,
400
+            this.requestHeader,
401
+            param,
402
+          );
403
+        }
404
+      },
405
+    );
406
+  }
333 407
 }
334 408
 
335 409
 export { Client };

+ 26
- 0
packages/cts-core/src/error.ts View File

@@ -0,0 +1,26 @@
1
+export class WebsocketError {
2
+  private _code: number;
3
+  private _msg: string;
4
+
5
+  /**
6
+   * 构造函数
7
+   */
8
+  public constructor(code: number, msg: string) {
9
+    this._code = code;
10
+    this._msg = msg;
11
+  }
12
+
13
+  /**
14
+   * 返回错误码
15
+   */
16
+  public get code(): number {
17
+    return this._code;
18
+  }
19
+
20
+  /**
21
+   * 返回具体的错误信息
22
+   */
23
+  public get msg(): string {
24
+    return this._msg;
25
+  }
26
+}