@cloudpss/ubrpc 0.4.12 → 0.4.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth.d.ts +5 -5
- package/dist/auth.js +51 -51
- package/dist/client.d.ts +16 -16
- package/dist/client.js +47 -47
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/server.d.ts +44 -44
- package/dist/server.js +117 -117
- package/dist/socket.d.ts +67 -67
- package/dist/socket.js +296 -296
- package/dist/socket.js.map +1 -1
- package/dist/types/payload.d.ts +99 -99
- package/dist/types/payload.js +1 -1
- package/dist/types/utils.d.ts +32 -32
- package/dist/types/utils.js +21 -21
- package/dist/utils/messaging.d.ts +7 -7
- package/dist/utils/messaging.js +8 -8
- package/dist/utils/serialize.d.ts +9 -9
- package/dist/utils/serialize.js +72 -72
- package/dist/utils/websocket.d.ts +4 -4
- package/dist/utils/websocket.js +20 -20
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
- package/tests/server.js +8 -3
package/dist/socket.js
CHANGED
|
@@ -1,297 +1,297 @@
|
|
|
1
|
-
import { from, Observable } from 'rxjs';
|
|
2
|
-
import { send } from './utils/messaging.js';
|
|
3
|
-
import { decodePayload, deserializeError, serializeError } from './utils/serialize.js';
|
|
4
|
-
import { ready } from './utils/websocket.js';
|
|
5
|
-
/** RPC 连接 */
|
|
6
|
-
export class RpcSocket {
|
|
7
|
-
constructor(id, local) {
|
|
8
|
-
this.id = id;
|
|
9
|
-
this.__handlers = Object.freeze({
|
|
10
|
-
open: (ev) => this.onOpen(ev),
|
|
11
|
-
close: (ev) => this.onClose(ev),
|
|
12
|
-
error: (ev) => this.onError(ev),
|
|
13
|
-
message: (ev) => this.onMessage(ev),
|
|
14
|
-
});
|
|
15
|
-
this.localSubscription = new Map();
|
|
16
|
-
/** 序列号 */
|
|
17
|
-
this.seq = 0;
|
|
18
|
-
this.pendingCalls = new Map();
|
|
19
|
-
this.pendingSubscriptions = new Map();
|
|
20
|
-
this.__local = local;
|
|
21
|
-
this.makeReady();
|
|
22
|
-
}
|
|
23
|
-
/** 本地认证信息 */
|
|
24
|
-
get localMetadata() {
|
|
25
|
-
return this._localMetadata;
|
|
26
|
-
}
|
|
27
|
-
/** 远程认证信息 */
|
|
28
|
-
get remoteMetadata() {
|
|
29
|
-
return this._remoteMetadata;
|
|
30
|
-
}
|
|
31
|
-
/** 连接是否已认证 */
|
|
32
|
-
get authenticated() {
|
|
33
|
-
return this._remoteMetadata != null;
|
|
34
|
-
}
|
|
35
|
-
/** 用于响应调用的本地对象 */
|
|
36
|
-
get local() {
|
|
37
|
-
return this.__local;
|
|
38
|
-
}
|
|
39
|
-
/** 作为底层传输的 WebSocket */
|
|
40
|
-
get socket() {
|
|
41
|
-
if (!this.__socket)
|
|
42
|
-
throw new Error(`Socket not initialized`);
|
|
43
|
-
return this.__socket;
|
|
44
|
-
}
|
|
45
|
-
set socket(value) {
|
|
46
|
-
if (this.__socket === value)
|
|
47
|
-
return;
|
|
48
|
-
const callbacks = this.makeReady();
|
|
49
|
-
const oldValue = this.__socket;
|
|
50
|
-
this.__socket = value;
|
|
51
|
-
void this.initSocket(oldValue, value).then(...callbacks);
|
|
52
|
-
}
|
|
53
|
-
/** 创建 ready Promise */
|
|
54
|
-
makeReady() {
|
|
55
|
-
if (this.__readyCallbacks != null)
|
|
56
|
-
return this.__readyCallbacks;
|
|
57
|
-
const ready = new Promise((...args) => (this.__readyCallbacks = args));
|
|
58
|
-
ready
|
|
59
|
-
.catch(() => {
|
|
60
|
-
// Avoid unhandled rejection
|
|
61
|
-
})
|
|
62
|
-
.finally(() => {
|
|
63
|
-
if (this.ready === ready)
|
|
64
|
-
this.__readyCallbacks = undefined;
|
|
65
|
-
});
|
|
66
|
-
this.ready = ready;
|
|
67
|
-
if (!this.__readyCallbacks)
|
|
68
|
-
throw new Error(`Bad promise`);
|
|
69
|
-
return this.__readyCallbacks;
|
|
70
|
-
}
|
|
71
|
-
/** 初始化 WebSocket */
|
|
72
|
-
async initSocket(oldValue, newValue) {
|
|
73
|
-
try {
|
|
74
|
-
if (oldValue) {
|
|
75
|
-
oldValue.removeEventListener('open', this.__handlers.open);
|
|
76
|
-
oldValue.removeEventListener('close', this.__handlers.close);
|
|
77
|
-
oldValue.removeEventListener('error', this.__handlers.error);
|
|
78
|
-
oldValue.removeEventListener('message', this.__handlers.message);
|
|
79
|
-
}
|
|
80
|
-
await ready(newValue);
|
|
81
|
-
const info = await this.authSocket();
|
|
82
|
-
if (this.__socket === newValue) {
|
|
83
|
-
newValue.addEventListener('open', this.__handlers.open);
|
|
84
|
-
newValue.addEventListener('close', this.__handlers.close);
|
|
85
|
-
newValue.addEventListener('error', this.__handlers.error);
|
|
86
|
-
newValue.addEventListener('message', this.__handlers.message);
|
|
87
|
-
this._remoteMetadata = info ?? {};
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
catch (ex) {
|
|
91
|
-
this._remoteMetadata = undefined;
|
|
92
|
-
throw ex;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
/** 响应 WebSocket error */
|
|
96
|
-
onError(_ev) {
|
|
97
|
-
this._remoteMetadata = undefined;
|
|
98
|
-
this.makeReady();
|
|
99
|
-
}
|
|
100
|
-
/** 响应 WebSocket open */
|
|
101
|
-
onOpen(_ev) {
|
|
102
|
-
//
|
|
103
|
-
}
|
|
104
|
-
/** 响应 WebSocket close */
|
|
105
|
-
onClose(ev) {
|
|
106
|
-
this._remoteMetadata = undefined;
|
|
107
|
-
if (ev.code === 1000) {
|
|
108
|
-
this.destroy();
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
this.makeReady();
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
/** 响应 WebSocket message */
|
|
115
|
-
onMessage(ev) {
|
|
116
|
-
const payload = decodePayload(ev.data);
|
|
117
|
-
let error;
|
|
118
|
-
if (payload) {
|
|
119
|
-
const handled = this.onPayload(payload);
|
|
120
|
-
if (!handled)
|
|
121
|
-
error = [payload.seq, `Unrecognized message, not handled.`];
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
error = [this.nextSeq(), `Invalid message, unknown format.`];
|
|
125
|
-
}
|
|
126
|
-
if (error) {
|
|
127
|
-
void this.sendPayload('error', {
|
|
128
|
-
seq: error[0],
|
|
129
|
-
error: serializeError(new SyntaxError(error[1])),
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
/** 响应 Rpc 消息 */
|
|
134
|
-
onPayload(payload) {
|
|
135
|
-
switch (payload.type) {
|
|
136
|
-
case 'call':
|
|
137
|
-
case 'notify':
|
|
138
|
-
void this.localCall(payload);
|
|
139
|
-
return true;
|
|
140
|
-
case 'return': {
|
|
141
|
-
const pending = this.pendingCalls.get(payload.seq);
|
|
142
|
-
// 即使不存在等待的请求,也认为响应是有效的
|
|
143
|
-
if (!pending)
|
|
144
|
-
return true;
|
|
145
|
-
this.pendingCalls.delete(payload.seq);
|
|
146
|
-
if (payload.error) {
|
|
147
|
-
pending[1](deserializeError(payload.error));
|
|
148
|
-
}
|
|
149
|
-
else {
|
|
150
|
-
pending[0](payload.result);
|
|
151
|
-
}
|
|
152
|
-
return true;
|
|
153
|
-
}
|
|
154
|
-
case 'subscribe':
|
|
155
|
-
void this.localSubscribe(payload);
|
|
156
|
-
return true;
|
|
157
|
-
case 'unsubscribe': {
|
|
158
|
-
const subscription = this.localSubscription.get(payload.seq);
|
|
159
|
-
// 即使不存在对应订阅,也认为响应是有效的
|
|
160
|
-
if (!subscription)
|
|
161
|
-
return true;
|
|
162
|
-
subscription.unsubscribe();
|
|
163
|
-
this.localSubscription.delete(payload.seq);
|
|
164
|
-
return true;
|
|
165
|
-
}
|
|
166
|
-
case 'publish': {
|
|
167
|
-
const subscriber = this.pendingSubscriptions.get(payload.seq);
|
|
168
|
-
// 即使不存在对应订阅,也认为响应是有效的
|
|
169
|
-
if (!subscriber) {
|
|
170
|
-
void this.sendPayload('unsubscribe', { seq: payload.seq });
|
|
171
|
-
return true;
|
|
172
|
-
}
|
|
173
|
-
if (payload.error) {
|
|
174
|
-
subscriber.error(deserializeError(payload.error));
|
|
175
|
-
}
|
|
176
|
-
else if (payload.complete) {
|
|
177
|
-
subscriber.complete();
|
|
178
|
-
}
|
|
179
|
-
else {
|
|
180
|
-
subscriber.next(payload.next);
|
|
181
|
-
}
|
|
182
|
-
return true;
|
|
183
|
-
}
|
|
184
|
-
case 'error':
|
|
185
|
-
return true;
|
|
186
|
-
default:
|
|
187
|
-
return false;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
/** 调用本地方法 */
|
|
191
|
-
async localCall(payload) {
|
|
192
|
-
const noReturn = payload.type === 'notify';
|
|
193
|
-
const method = this.local ? this.local[payload.method] : undefined;
|
|
194
|
-
const seq = payload.seq;
|
|
195
|
-
if (typeof method != 'function') {
|
|
196
|
-
if (noReturn)
|
|
197
|
-
return;
|
|
198
|
-
return this.sendPayload('return', {
|
|
199
|
-
seq,
|
|
200
|
-
error: serializeError(new TypeError(`${payload.method} is not a function`)),
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
try {
|
|
204
|
-
const result = await Reflect.apply(method, this.local, payload.args);
|
|
205
|
-
if (noReturn)
|
|
206
|
-
return;
|
|
207
|
-
return this.sendPayload('return', { seq, result });
|
|
208
|
-
}
|
|
209
|
-
catch (ex) {
|
|
210
|
-
if (noReturn)
|
|
211
|
-
return;
|
|
212
|
-
return this.sendPayload('return', { seq, error: serializeError(ex) });
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
/** 调用本地方法 */
|
|
216
|
-
async localSubscribe(payload) {
|
|
217
|
-
const method = this.local ? this.local[payload.method] : undefined;
|
|
218
|
-
const seq = payload.seq;
|
|
219
|
-
if (typeof method != 'function') {
|
|
220
|
-
return this.sendPayload('publish', {
|
|
221
|
-
seq,
|
|
222
|
-
error: serializeError(new TypeError(`${payload.method} is not a function`)),
|
|
223
|
-
});
|
|
224
|
-
}
|
|
225
|
-
try {
|
|
226
|
-
const result = from((await Reflect.apply(method, this.local, payload.args)));
|
|
227
|
-
const subscription = result.subscribe({
|
|
228
|
-
next: (value) => {
|
|
229
|
-
void this.sendPayload('publish', { seq, next: value });
|
|
230
|
-
},
|
|
231
|
-
error: (err) => {
|
|
232
|
-
this.localSubscription.delete(payload.seq);
|
|
233
|
-
void this.sendPayload('publish', { seq, error: serializeError(err) });
|
|
234
|
-
},
|
|
235
|
-
complete: () => {
|
|
236
|
-
this.localSubscription.delete(payload.seq);
|
|
237
|
-
void this.sendPayload('publish', { seq, complete: true });
|
|
238
|
-
},
|
|
239
|
-
});
|
|
240
|
-
this.localSubscription.set(seq, subscription);
|
|
241
|
-
}
|
|
242
|
-
catch (ex) {
|
|
243
|
-
return this.sendPayload('publish', { seq, error: serializeError(ex) });
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
/** 发送数据 */
|
|
247
|
-
async sendPayload(type, info) {
|
|
248
|
-
await this.ready;
|
|
249
|
-
send(this.socket, type, info);
|
|
250
|
-
}
|
|
251
|
-
/** 获取下一个序列号 */
|
|
252
|
-
nextSeq() {
|
|
253
|
-
const seq = this.seq;
|
|
254
|
-
this.seq += 2;
|
|
255
|
-
return seq;
|
|
256
|
-
}
|
|
257
|
-
/** 调用远程方法 */
|
|
258
|
-
call(method, ...args) {
|
|
259
|
-
return new Promise((resolve, reject) => {
|
|
260
|
-
const seq = this.nextSeq();
|
|
261
|
-
void this.sendPayload('call', { seq, method, args });
|
|
262
|
-
this.pendingCalls.set(seq, [resolve, reject]);
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
/** 调用远程方法,放弃返回值 */
|
|
266
|
-
notify(method, ...args) {
|
|
267
|
-
const seq = this.nextSeq();
|
|
268
|
-
void this.sendPayload('notify', { seq, method, args });
|
|
269
|
-
}
|
|
270
|
-
/** 调用远程订阅 */
|
|
271
|
-
subscribe(method, ...args) {
|
|
272
|
-
return new Observable((subscriber) => {
|
|
273
|
-
const seq = this.nextSeq();
|
|
274
|
-
void this.sendPayload('subscribe', { seq, method, args });
|
|
275
|
-
this.pendingSubscriptions.set(seq, subscriber);
|
|
276
|
-
return () => {
|
|
277
|
-
this.pendingSubscriptions.delete(seq);
|
|
278
|
-
void this.sendPayload('unsubscribe', { seq });
|
|
279
|
-
};
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
/** 结束 */
|
|
283
|
-
destroy() {
|
|
284
|
-
if (this.__socket &&
|
|
285
|
-
(this.__socket.readyState === this.__socket.CONNECTING || this.__socket.readyState === this.__socket.OPEN)) {
|
|
286
|
-
this.__socket.close(1000);
|
|
287
|
-
this.__socket = undefined;
|
|
288
|
-
}
|
|
289
|
-
this.localSubscription.forEach((s) => s.unsubscribe());
|
|
290
|
-
this.localSubscription.clear();
|
|
291
|
-
this.pendingCalls.forEach(([, reject]) => reject(new Error(`RPC Socket closed.`)));
|
|
292
|
-
this.pendingCalls.clear();
|
|
293
|
-
this.pendingSubscriptions.forEach((s) => s.error(new Error(`RPC Socket closed.`)));
|
|
294
|
-
this.pendingSubscriptions.clear();
|
|
295
|
-
}
|
|
296
|
-
}
|
|
1
|
+
import { from, Observable, Subscriber, Subscription } from 'rxjs';
|
|
2
|
+
import { send } from './utils/messaging.js';
|
|
3
|
+
import { decodePayload, deserializeError, serializeError } from './utils/serialize.js';
|
|
4
|
+
import { ready } from './utils/websocket.js';
|
|
5
|
+
/** RPC 连接 */
|
|
6
|
+
export class RpcSocket {
|
|
7
|
+
constructor(id, local) {
|
|
8
|
+
this.id = id;
|
|
9
|
+
this.__handlers = Object.freeze({
|
|
10
|
+
open: (ev) => this.onOpen(ev),
|
|
11
|
+
close: (ev) => this.onClose(ev),
|
|
12
|
+
error: (ev) => this.onError(ev),
|
|
13
|
+
message: (ev) => this.onMessage(ev),
|
|
14
|
+
});
|
|
15
|
+
this.localSubscription = new Map();
|
|
16
|
+
/** 序列号 */
|
|
17
|
+
this.seq = 0;
|
|
18
|
+
this.pendingCalls = new Map();
|
|
19
|
+
this.pendingSubscriptions = new Map();
|
|
20
|
+
this.__local = local;
|
|
21
|
+
this.makeReady();
|
|
22
|
+
}
|
|
23
|
+
/** 本地认证信息 */
|
|
24
|
+
get localMetadata() {
|
|
25
|
+
return this._localMetadata;
|
|
26
|
+
}
|
|
27
|
+
/** 远程认证信息 */
|
|
28
|
+
get remoteMetadata() {
|
|
29
|
+
return this._remoteMetadata;
|
|
30
|
+
}
|
|
31
|
+
/** 连接是否已认证 */
|
|
32
|
+
get authenticated() {
|
|
33
|
+
return this._remoteMetadata != null;
|
|
34
|
+
}
|
|
35
|
+
/** 用于响应调用的本地对象 */
|
|
36
|
+
get local() {
|
|
37
|
+
return this.__local;
|
|
38
|
+
}
|
|
39
|
+
/** 作为底层传输的 WebSocket */
|
|
40
|
+
get socket() {
|
|
41
|
+
if (!this.__socket)
|
|
42
|
+
throw new Error(`Socket not initialized`);
|
|
43
|
+
return this.__socket;
|
|
44
|
+
}
|
|
45
|
+
set socket(value) {
|
|
46
|
+
if (this.__socket === value)
|
|
47
|
+
return;
|
|
48
|
+
const callbacks = this.makeReady();
|
|
49
|
+
const oldValue = this.__socket;
|
|
50
|
+
this.__socket = value;
|
|
51
|
+
void this.initSocket(oldValue, value).then(...callbacks);
|
|
52
|
+
}
|
|
53
|
+
/** 创建 ready Promise */
|
|
54
|
+
makeReady() {
|
|
55
|
+
if (this.__readyCallbacks != null)
|
|
56
|
+
return this.__readyCallbacks;
|
|
57
|
+
const ready = new Promise((...args) => (this.__readyCallbacks = args));
|
|
58
|
+
ready
|
|
59
|
+
.catch(() => {
|
|
60
|
+
// Avoid unhandled rejection
|
|
61
|
+
})
|
|
62
|
+
.finally(() => {
|
|
63
|
+
if (this.ready === ready)
|
|
64
|
+
this.__readyCallbacks = undefined;
|
|
65
|
+
});
|
|
66
|
+
this.ready = ready;
|
|
67
|
+
if (!this.__readyCallbacks)
|
|
68
|
+
throw new Error(`Bad promise`);
|
|
69
|
+
return this.__readyCallbacks;
|
|
70
|
+
}
|
|
71
|
+
/** 初始化 WebSocket */
|
|
72
|
+
async initSocket(oldValue, newValue) {
|
|
73
|
+
try {
|
|
74
|
+
if (oldValue) {
|
|
75
|
+
oldValue.removeEventListener('open', this.__handlers.open);
|
|
76
|
+
oldValue.removeEventListener('close', this.__handlers.close);
|
|
77
|
+
oldValue.removeEventListener('error', this.__handlers.error);
|
|
78
|
+
oldValue.removeEventListener('message', this.__handlers.message);
|
|
79
|
+
}
|
|
80
|
+
await ready(newValue);
|
|
81
|
+
const info = await this.authSocket();
|
|
82
|
+
if (this.__socket === newValue) {
|
|
83
|
+
newValue.addEventListener('open', this.__handlers.open);
|
|
84
|
+
newValue.addEventListener('close', this.__handlers.close);
|
|
85
|
+
newValue.addEventListener('error', this.__handlers.error);
|
|
86
|
+
newValue.addEventListener('message', this.__handlers.message);
|
|
87
|
+
this._remoteMetadata = info ?? {};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch (ex) {
|
|
91
|
+
this._remoteMetadata = undefined;
|
|
92
|
+
throw ex;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/** 响应 WebSocket error */
|
|
96
|
+
onError(_ev) {
|
|
97
|
+
this._remoteMetadata = undefined;
|
|
98
|
+
this.makeReady();
|
|
99
|
+
}
|
|
100
|
+
/** 响应 WebSocket open */
|
|
101
|
+
onOpen(_ev) {
|
|
102
|
+
//
|
|
103
|
+
}
|
|
104
|
+
/** 响应 WebSocket close */
|
|
105
|
+
onClose(ev) {
|
|
106
|
+
this._remoteMetadata = undefined;
|
|
107
|
+
if (ev.code === 1000) {
|
|
108
|
+
this.destroy();
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
this.makeReady();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/** 响应 WebSocket message */
|
|
115
|
+
onMessage(ev) {
|
|
116
|
+
const payload = decodePayload(ev.data);
|
|
117
|
+
let error;
|
|
118
|
+
if (payload) {
|
|
119
|
+
const handled = this.onPayload(payload);
|
|
120
|
+
if (!handled)
|
|
121
|
+
error = [payload.seq, `Unrecognized message, not handled.`];
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
error = [this.nextSeq(), `Invalid message, unknown format.`];
|
|
125
|
+
}
|
|
126
|
+
if (error) {
|
|
127
|
+
void this.sendPayload('error', {
|
|
128
|
+
seq: error[0],
|
|
129
|
+
error: serializeError(new SyntaxError(error[1])),
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/** 响应 Rpc 消息 */
|
|
134
|
+
onPayload(payload) {
|
|
135
|
+
switch (payload.type) {
|
|
136
|
+
case 'call':
|
|
137
|
+
case 'notify':
|
|
138
|
+
void this.localCall(payload);
|
|
139
|
+
return true;
|
|
140
|
+
case 'return': {
|
|
141
|
+
const pending = this.pendingCalls.get(payload.seq);
|
|
142
|
+
// 即使不存在等待的请求,也认为响应是有效的
|
|
143
|
+
if (!pending)
|
|
144
|
+
return true;
|
|
145
|
+
this.pendingCalls.delete(payload.seq);
|
|
146
|
+
if (payload.error) {
|
|
147
|
+
pending[1](deserializeError(payload.error));
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
pending[0](payload.result);
|
|
151
|
+
}
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
case 'subscribe':
|
|
155
|
+
void this.localSubscribe(payload);
|
|
156
|
+
return true;
|
|
157
|
+
case 'unsubscribe': {
|
|
158
|
+
const subscription = this.localSubscription.get(payload.seq);
|
|
159
|
+
// 即使不存在对应订阅,也认为响应是有效的
|
|
160
|
+
if (!subscription)
|
|
161
|
+
return true;
|
|
162
|
+
subscription.unsubscribe();
|
|
163
|
+
this.localSubscription.delete(payload.seq);
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
case 'publish': {
|
|
167
|
+
const subscriber = this.pendingSubscriptions.get(payload.seq);
|
|
168
|
+
// 即使不存在对应订阅,也认为响应是有效的
|
|
169
|
+
if (!subscriber) {
|
|
170
|
+
void this.sendPayload('unsubscribe', { seq: payload.seq });
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
if (payload.error) {
|
|
174
|
+
subscriber.error(deserializeError(payload.error));
|
|
175
|
+
}
|
|
176
|
+
else if (payload.complete) {
|
|
177
|
+
subscriber.complete();
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
subscriber.next(payload.next);
|
|
181
|
+
}
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
case 'error':
|
|
185
|
+
return true;
|
|
186
|
+
default:
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/** 调用本地方法 */
|
|
191
|
+
async localCall(payload) {
|
|
192
|
+
const noReturn = payload.type === 'notify';
|
|
193
|
+
const method = this.local ? this.local[payload.method] : undefined;
|
|
194
|
+
const seq = payload.seq;
|
|
195
|
+
if (typeof method != 'function') {
|
|
196
|
+
if (noReturn)
|
|
197
|
+
return;
|
|
198
|
+
return this.sendPayload('return', {
|
|
199
|
+
seq,
|
|
200
|
+
error: serializeError(new TypeError(`${payload.method} is not a function`)),
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
try {
|
|
204
|
+
const result = await Reflect.apply(method, this.local, payload.args);
|
|
205
|
+
if (noReturn)
|
|
206
|
+
return;
|
|
207
|
+
return this.sendPayload('return', { seq, result });
|
|
208
|
+
}
|
|
209
|
+
catch (ex) {
|
|
210
|
+
if (noReturn)
|
|
211
|
+
return;
|
|
212
|
+
return this.sendPayload('return', { seq, error: serializeError(ex) });
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/** 调用本地方法 */
|
|
216
|
+
async localSubscribe(payload) {
|
|
217
|
+
const method = this.local ? this.local[payload.method] : undefined;
|
|
218
|
+
const seq = payload.seq;
|
|
219
|
+
if (typeof method != 'function') {
|
|
220
|
+
return this.sendPayload('publish', {
|
|
221
|
+
seq,
|
|
222
|
+
error: serializeError(new TypeError(`${payload.method} is not a function`)),
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
try {
|
|
226
|
+
const result = from((await Reflect.apply(method, this.local, payload.args)));
|
|
227
|
+
const subscription = result.subscribe({
|
|
228
|
+
next: (value) => {
|
|
229
|
+
void this.sendPayload('publish', { seq, next: value });
|
|
230
|
+
},
|
|
231
|
+
error: (err) => {
|
|
232
|
+
this.localSubscription.delete(payload.seq);
|
|
233
|
+
void this.sendPayload('publish', { seq, error: serializeError(err) });
|
|
234
|
+
},
|
|
235
|
+
complete: () => {
|
|
236
|
+
this.localSubscription.delete(payload.seq);
|
|
237
|
+
void this.sendPayload('publish', { seq, complete: true });
|
|
238
|
+
},
|
|
239
|
+
});
|
|
240
|
+
this.localSubscription.set(seq, subscription);
|
|
241
|
+
}
|
|
242
|
+
catch (ex) {
|
|
243
|
+
return this.sendPayload('publish', { seq, error: serializeError(ex) });
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
/** 发送数据 */
|
|
247
|
+
async sendPayload(type, info) {
|
|
248
|
+
await this.ready;
|
|
249
|
+
send(this.socket, type, info);
|
|
250
|
+
}
|
|
251
|
+
/** 获取下一个序列号 */
|
|
252
|
+
nextSeq() {
|
|
253
|
+
const seq = this.seq;
|
|
254
|
+
this.seq += 2;
|
|
255
|
+
return seq;
|
|
256
|
+
}
|
|
257
|
+
/** 调用远程方法 */
|
|
258
|
+
call(method, ...args) {
|
|
259
|
+
return new Promise((resolve, reject) => {
|
|
260
|
+
const seq = this.nextSeq();
|
|
261
|
+
void this.sendPayload('call', { seq, method, args });
|
|
262
|
+
this.pendingCalls.set(seq, [resolve, reject]);
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
/** 调用远程方法,放弃返回值 */
|
|
266
|
+
notify(method, ...args) {
|
|
267
|
+
const seq = this.nextSeq();
|
|
268
|
+
void this.sendPayload('notify', { seq, method, args });
|
|
269
|
+
}
|
|
270
|
+
/** 调用远程订阅 */
|
|
271
|
+
subscribe(method, ...args) {
|
|
272
|
+
return new Observable((subscriber) => {
|
|
273
|
+
const seq = this.nextSeq();
|
|
274
|
+
void this.sendPayload('subscribe', { seq, method, args });
|
|
275
|
+
this.pendingSubscriptions.set(seq, subscriber);
|
|
276
|
+
return () => {
|
|
277
|
+
this.pendingSubscriptions.delete(seq);
|
|
278
|
+
void this.sendPayload('unsubscribe', { seq });
|
|
279
|
+
};
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
/** 结束 */
|
|
283
|
+
destroy() {
|
|
284
|
+
if (this.__socket &&
|
|
285
|
+
(this.__socket.readyState === this.__socket.CONNECTING || this.__socket.readyState === this.__socket.OPEN)) {
|
|
286
|
+
this.__socket.close(1000);
|
|
287
|
+
this.__socket = undefined;
|
|
288
|
+
}
|
|
289
|
+
this.localSubscription.forEach((s) => s.unsubscribe());
|
|
290
|
+
this.localSubscription.clear();
|
|
291
|
+
this.pendingCalls.forEach(([, reject]) => reject(new Error(`RPC Socket closed.`)));
|
|
292
|
+
this.pendingCalls.clear();
|
|
293
|
+
this.pendingSubscriptions.forEach((s) => s.error(new Error(`RPC Socket closed.`)));
|
|
294
|
+
this.pendingSubscriptions.clear();
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
297
|
//# sourceMappingURL=socket.js.map
|
package/dist/socket.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"socket.js","sourceRoot":"","sources":["../src/socket.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"socket.js","sourceRoot":"","sources":["../src/socket.ts"],"names":[],"mappings":"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"}
|