@dxos/network-manager 2.33.9-dev.002e8917 → 2.33.9-dev.227ba79d
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/src/network-manager.blueprint-test.d.ts +3 -1
- package/dist/src/network-manager.blueprint-test.d.ts.map +1 -1
- package/dist/src/network-manager.blueprint-test.js +46 -17
- package/dist/src/network-manager.blueprint-test.js.map +1 -1
- package/dist/src/network-manager.browser-test.js +1 -1
- package/dist/src/network-manager.browser-test.js.map +1 -1
- package/dist/src/network-manager.d.ts.map +1 -1
- package/dist/src/network-manager.js +6 -6
- package/dist/src/network-manager.js.map +1 -1
- package/dist/src/network-manager.test.js +5 -4
- package/dist/src/network-manager.test.js.map +1 -1
- package/dist/src/proto/gen/dxos/credentials.d.ts +39 -0
- package/dist/src/proto/gen/dxos/credentials.d.ts.map +1 -1
- package/dist/src/proto/gen/dxos/halo/keys.d.ts +44 -2
- package/dist/src/proto/gen/dxos/halo/keys.d.ts.map +1 -1
- package/dist/src/proto/gen/dxos/halo/keys.js +4 -0
- package/dist/src/proto/gen/dxos/halo/keys.js.map +1 -1
- package/dist/src/proto/gen/dxos/mesh/signal.d.ts +74 -37
- package/dist/src/proto/gen/dxos/mesh/signal.d.ts.map +1 -1
- package/dist/src/proto/gen/dxos/mesh/signalMessage.d.ts +79 -0
- package/dist/src/proto/gen/dxos/mesh/signalMessage.d.ts.map +1 -0
- package/dist/src/proto/gen/dxos/mesh/signalMessage.js +3 -0
- package/dist/src/proto/gen/dxos/mesh/signalMessage.js.map +1 -0
- package/dist/src/proto/gen/google/protobuf.d.ts +8 -2
- package/dist/src/proto/gen/google/protobuf.d.ts.map +1 -1
- package/dist/src/proto/gen/index.d.ts +17 -5
- package/dist/src/proto/gen/index.d.ts.map +1 -1
- package/dist/src/proto/gen/index.js +1 -1
- package/dist/src/proto/gen/index.js.map +1 -1
- package/dist/src/proto/substitutions.d.ts +4 -0
- package/dist/src/proto/substitutions.d.ts.map +1 -1
- package/dist/src/proto/substitutions.js +3 -1
- package/dist/src/proto/substitutions.js.map +1 -1
- package/dist/src/signal/in-memory-signal-manager.d.ts +7 -7
- package/dist/src/signal/in-memory-signal-manager.d.ts.map +1 -1
- package/dist/src/signal/in-memory-signal-manager.js +29 -8
- package/dist/src/signal/in-memory-signal-manager.js.map +1 -1
- package/dist/src/signal/index.d.ts +1 -2
- package/dist/src/signal/index.d.ts.map +1 -1
- package/dist/src/signal/index.js +1 -2
- package/dist/src/signal/index.js.map +1 -1
- package/dist/src/signal/integration.test.d.ts +2 -0
- package/dist/src/signal/integration.test.d.ts.map +1 -0
- package/dist/src/signal/integration.test.js +102 -0
- package/dist/src/signal/integration.test.js.map +1 -0
- package/dist/src/signal/message-router.d.ts +7 -7
- package/dist/src/signal/message-router.d.ts.map +1 -1
- package/dist/src/signal/message-router.js +6 -1
- package/dist/src/signal/message-router.js.map +1 -1
- package/dist/src/signal/message-router.test.js +15 -19
- package/dist/src/signal/message-router.test.js.map +1 -1
- package/dist/src/signal/signal-client.d.ts +33 -18
- package/dist/src/signal/signal-client.d.ts.map +1 -1
- package/dist/src/signal/signal-client.js +102 -92
- package/dist/src/signal/signal-client.js.map +1 -1
- package/dist/src/signal/signal-client.test.js +60 -77
- package/dist/src/signal/signal-client.test.js.map +1 -1
- package/dist/src/signal/{websocket-signal-manager.d.ts → signal-manager-impl.d.ts} +13 -11
- package/dist/src/signal/signal-manager-impl.d.ts.map +1 -0
- package/dist/src/signal/signal-manager-impl.js +151 -0
- package/dist/src/signal/signal-manager-impl.js.map +1 -0
- package/dist/src/signal/signal-manager.d.ts +12 -11
- package/dist/src/signal/signal-manager.d.ts.map +1 -1
- package/dist/src/signal/signal-rpc-client.d.ts +19 -0
- package/dist/src/signal/signal-rpc-client.d.ts.map +1 -0
- package/dist/src/signal/signal-rpc-client.js +108 -0
- package/dist/src/signal/signal-rpc-client.js.map +1 -0
- package/dist/src/signal/signal-rpc-client.test.d.ts +2 -0
- package/dist/src/signal/signal-rpc-client.test.d.ts.map +1 -0
- package/dist/src/signal/signal-rpc-client.test.js +74 -0
- package/dist/src/signal/signal-rpc-client.test.js.map +1 -0
- package/dist/src/swarm/connection.d.ts +3 -3
- package/dist/src/swarm/connection.d.ts.map +1 -1
- package/dist/src/swarm/connection.js +1 -4
- package/dist/src/swarm/connection.js.map +1 -1
- package/dist/src/swarm/swarm.d.ts +6 -7
- package/dist/src/swarm/swarm.d.ts.map +1 -1
- package/dist/src/swarm/swarm.js +21 -17
- package/dist/src/swarm/swarm.js.map +1 -1
- package/dist/src/swarm/swarm.test.js +156 -117
- package/dist/src/swarm/swarm.test.js.map +1 -1
- package/dist/src/topology/fully-connected-topology.d.ts +0 -1
- package/dist/src/topology/fully-connected-topology.d.ts.map +1 -1
- package/dist/src/topology/fully-connected-topology.js +1 -6
- package/dist/src/topology/fully-connected-topology.js.map +1 -1
- package/dist/src/topology/mmst-topology.d.ts +0 -1
- package/dist/src/topology/mmst-topology.d.ts.map +1 -1
- package/dist/src/topology/mmst-topology.js +1 -6
- package/dist/src/topology/mmst-topology.js.map +1 -1
- package/dist/src/topology/star-topology.d.ts +0 -1
- package/dist/src/topology/star-topology.d.ts.map +1 -1
- package/dist/src/topology/star-topology.js +1 -6
- package/dist/src/topology/star-topology.js.map +1 -1
- package/dist/src/topology/topology.d.ts +0 -6
- package/dist/src/topology/topology.d.ts.map +1 -1
- package/dist/src/transport/in-memory-transport.d.ts +2 -2
- package/dist/src/transport/in-memory-transport.d.ts.map +1 -1
- package/dist/src/transport/in-memory-transport.js.map +1 -1
- package/dist/src/transport/transport.d.ts +3 -3
- package/dist/src/transport/transport.d.ts.map +1 -1
- package/dist/src/transport/webrtc-transport.d.ts +3 -3
- package/dist/src/transport/webrtc-transport.d.ts.map +1 -1
- package/dist/src/transport/webrtc-transport.js.map +1 -1
- package/dist/tests-setup.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +14 -12
- package/src/network-manager.blueprint-test.ts +57 -22
- package/src/network-manager.browser-test.ts +1 -1
- package/src/network-manager.test.ts +8 -7
- package/src/network-manager.ts +8 -9
- package/src/proto/defs/dxos/mesh/signal.proto +53 -35
- package/src/proto/defs/dxos/mesh/signalMessage.proto +51 -0
- package/src/proto/gen/dxos/credentials.ts +40 -0
- package/src/proto/gen/dxos/halo/keys.ts +45 -2
- package/src/proto/gen/dxos/mesh/signal.ts +73 -37
- package/src/proto/gen/dxos/mesh/signalMessage.ts +83 -0
- package/src/proto/gen/google/protobuf.ts +9 -2
- package/src/proto/gen/index.ts +18 -6
- package/src/proto/substitutions.ts +3 -1
- package/src/signal/in-memory-signal-manager.ts +37 -12
- package/src/signal/index.ts +1 -2
- package/src/signal/integration.test.ts +117 -0
- package/src/signal/message-router.test.ts +36 -41
- package/src/signal/message-router.ts +22 -18
- package/src/signal/signal-client.test.ts +70 -92
- package/src/signal/signal-client.ts +119 -113
- package/src/signal/signal-manager-impl.ts +166 -0
- package/src/signal/signal-manager.ts +12 -12
- package/src/signal/signal-rpc-client.test.ts +86 -0
- package/src/signal/signal-rpc-client.ts +121 -0
- package/src/swarm/connection.ts +5 -8
- package/src/swarm/swarm.test.ts +208 -169
- package/src/swarm/swarm.ts +24 -20
- package/src/topology/fully-connected-topology.ts +1 -9
- package/src/topology/mmst-topology.ts +1 -9
- package/src/topology/star-topology.ts +1 -7
- package/src/topology/topology.ts +0 -7
- package/src/transport/in-memory-transport.ts +2 -2
- package/src/transport/transport.ts +3 -3
- package/src/transport/webrtc-transport.ts +3 -3
- package/dist/browser-mocha/bundle.js +0 -119276
- package/dist/browser-mocha/main.js +0 -27
- package/dist/src/signal/websocket-rpc.d.ts +0 -30
- package/dist/src/signal/websocket-rpc.d.ts.map +0 -1
- package/dist/src/signal/websocket-rpc.js +0 -203
- package/dist/src/signal/websocket-rpc.js.map +0 -1
- package/dist/src/signal/websocket-signal-manager.d.ts.map +0 -1
- package/dist/src/signal/websocket-signal-manager.js +0 -134
- package/dist/src/signal/websocket-signal-manager.js.map +0 -1
- package/src/signal/websocket-rpc.ts +0 -208
- package/src/signal/websocket-signal-manager.ts +0 -158
|
@@ -10,9 +10,8 @@ import { Awaited } from '@dxos/async';
|
|
|
10
10
|
import { PublicKey } from '@dxos/protocols';
|
|
11
11
|
import { createTestBroker } from '@dxos/signal';
|
|
12
12
|
import { afterTest } from '@dxos/testutils';
|
|
13
|
-
import { randomInt } from '@dxos/util';
|
|
14
13
|
|
|
15
|
-
import { Answer,
|
|
14
|
+
import { Answer, SignalMessage } from '../proto/gen/dxos/mesh/signalMessage';
|
|
16
15
|
import { MessageRouter } from './message-router';
|
|
17
16
|
import { SignalClient } from './signal-client';
|
|
18
17
|
|
|
@@ -22,11 +21,9 @@ describe('MessageRouter', () => {
|
|
|
22
21
|
let peer2: PublicKey;
|
|
23
22
|
|
|
24
23
|
let broker1: Awaited<ReturnType<typeof createTestBroker>>;
|
|
25
|
-
const signalApiPort1 = randomInt(10000, 50000);
|
|
26
|
-
const signalApiUrl1 = 'http://0.0.0.0:' + signalApiPort1;
|
|
27
24
|
|
|
28
25
|
before(async () => {
|
|
29
|
-
broker1 = await createTestBroker(
|
|
26
|
+
broker1 = await createTestBroker();
|
|
30
27
|
});
|
|
31
28
|
|
|
32
29
|
beforeEach(() => {
|
|
@@ -35,9 +32,8 @@ describe('MessageRouter', () => {
|
|
|
35
32
|
peer2 = PublicKey.random();
|
|
36
33
|
});
|
|
37
34
|
|
|
38
|
-
after(
|
|
39
|
-
|
|
40
|
-
await broker1.stop();
|
|
35
|
+
after(() => {
|
|
36
|
+
broker1.stop();
|
|
41
37
|
});
|
|
42
38
|
|
|
43
39
|
const createSignalClientAndMessageRouter = async ({
|
|
@@ -46,15 +42,15 @@ describe('MessageRouter', () => {
|
|
|
46
42
|
onOffer = async () => ({ accept: true })
|
|
47
43
|
}: {
|
|
48
44
|
signalApiUrl: string;
|
|
49
|
-
onSignal?: (msg:
|
|
50
|
-
onOffer?: (msg:
|
|
45
|
+
onSignal?: (msg: SignalMessage) => Promise<void>;
|
|
46
|
+
onOffer?: (msg: SignalMessage) => Promise<Answer>;
|
|
51
47
|
}) => {
|
|
52
48
|
|
|
53
49
|
// eslint-disable-next-line prefer-const
|
|
54
50
|
let api: SignalClient;
|
|
55
51
|
const router: MessageRouter = new MessageRouter({
|
|
56
52
|
// todo(mykola): added catch to avoid not finished request.
|
|
57
|
-
sendMessage: (msg:
|
|
53
|
+
sendMessage: (msg: SignalMessage) => api.signal(msg).catch((_) => { }),
|
|
58
54
|
onSignal: onSignal,
|
|
59
55
|
onOffer: onOffer
|
|
60
56
|
});
|
|
@@ -62,8 +58,7 @@ describe('MessageRouter', () => {
|
|
|
62
58
|
|
|
63
59
|
api = new SignalClient(
|
|
64
60
|
signalApiUrl,
|
|
65
|
-
|
|
66
|
-
async (msg: Message) => router.receiveMessage(msg)
|
|
61
|
+
async (msg: SignalMessage) => router.receiveMessage(msg)
|
|
67
62
|
);
|
|
68
63
|
|
|
69
64
|
afterTest(() => api.close());
|
|
@@ -74,19 +69,19 @@ describe('MessageRouter', () => {
|
|
|
74
69
|
};
|
|
75
70
|
|
|
76
71
|
test('signaling between 2 clients', async () => {
|
|
77
|
-
const signalMock1 = mockFn<(msg:
|
|
78
|
-
const { api: api1 } = await createSignalClientAndMessageRouter({ signalApiUrl:
|
|
79
|
-
const { api: api2, router: router2 } = await createSignalClientAndMessageRouter({ signalApiUrl:
|
|
72
|
+
const signalMock1 = mockFn<(msg: SignalMessage) => Promise<void>>().resolvesTo();
|
|
73
|
+
const { api: api1 } = await createSignalClientAndMessageRouter({ signalApiUrl: broker1.url(), onSignal: signalMock1 });
|
|
74
|
+
const { api: api2, router: router2 } = await createSignalClientAndMessageRouter({ signalApiUrl: broker1.url() });
|
|
80
75
|
|
|
81
76
|
await api1.join(topic, peer1);
|
|
82
77
|
await api2.join(topic, peer2);
|
|
83
78
|
|
|
84
|
-
const msg:
|
|
79
|
+
const msg: SignalMessage = {
|
|
85
80
|
id: peer2,
|
|
86
81
|
remoteId: peer1,
|
|
87
82
|
sessionId: PublicKey.random(),
|
|
88
83
|
topic,
|
|
89
|
-
data: { signal: { json: '
|
|
84
|
+
data: { signal: { json: JSON.stringify({ 'asd': 'asd' }) } }
|
|
90
85
|
};
|
|
91
86
|
await router2.signal(msg);
|
|
92
87
|
|
|
@@ -98,14 +93,14 @@ describe('MessageRouter', () => {
|
|
|
98
93
|
test('offer/answer', async () => {
|
|
99
94
|
const { api: api1, router: router1 } = await createSignalClientAndMessageRouter(
|
|
100
95
|
{
|
|
101
|
-
signalApiUrl:
|
|
96
|
+
signalApiUrl: broker1.url(),
|
|
102
97
|
onSignal: (async () => { }) as any,
|
|
103
98
|
onOffer:
|
|
104
99
|
async () => ({ accept: true })
|
|
105
100
|
});
|
|
106
101
|
const { api: api2 } = await createSignalClientAndMessageRouter(
|
|
107
102
|
{
|
|
108
|
-
signalApiUrl:
|
|
103
|
+
signalApiUrl: broker1.url(),
|
|
109
104
|
onSignal: (async () => { }) as any,
|
|
110
105
|
onOffer:
|
|
111
106
|
async () => ({ accept: true })
|
|
@@ -125,26 +120,26 @@ describe('MessageRouter', () => {
|
|
|
125
120
|
}).timeout(5_000);
|
|
126
121
|
|
|
127
122
|
test('signaling between 3 clients', async () => {
|
|
128
|
-
const signalMock1 = mockFn<(msg:
|
|
123
|
+
const signalMock1 = mockFn<(msg: SignalMessage) => Promise<void>>().resolvesTo();
|
|
129
124
|
const { api: api1, router: router1 } = await createSignalClientAndMessageRouter(
|
|
130
125
|
{
|
|
131
|
-
signalApiUrl:
|
|
126
|
+
signalApiUrl: broker1.url(),
|
|
132
127
|
onSignal: signalMock1,
|
|
133
128
|
onOffer:
|
|
134
129
|
async () => ({ accept: true })
|
|
135
130
|
});
|
|
136
|
-
const signalMock2 = mockFn<(msg:
|
|
131
|
+
const signalMock2 = mockFn<(msg: SignalMessage) => Promise<void>>().resolvesTo();
|
|
137
132
|
const { api: api2, router: router2 } = await createSignalClientAndMessageRouter(
|
|
138
133
|
{
|
|
139
|
-
signalApiUrl:
|
|
134
|
+
signalApiUrl: broker1.url(),
|
|
140
135
|
onSignal: signalMock2,
|
|
141
136
|
onOffer:
|
|
142
137
|
async () => ({ accept: true })
|
|
143
138
|
});
|
|
144
|
-
const signalMock3 = mockFn<(msg:
|
|
139
|
+
const signalMock3 = mockFn<(msg: SignalMessage) => Promise<void>>().resolvesTo();
|
|
145
140
|
const { api: api3, router: router3 } = await createSignalClientAndMessageRouter(
|
|
146
141
|
{
|
|
147
|
-
signalApiUrl:
|
|
142
|
+
signalApiUrl: broker1.url(),
|
|
148
143
|
onSignal: signalMock3,
|
|
149
144
|
onOffer:
|
|
150
145
|
async () => ({ accept: true })
|
|
@@ -156,7 +151,7 @@ describe('MessageRouter', () => {
|
|
|
156
151
|
await api3.join(topic, peer3);
|
|
157
152
|
|
|
158
153
|
// sending signal from peer1 to peer3.
|
|
159
|
-
const msg1to3:
|
|
154
|
+
const msg1to3: SignalMessage = {
|
|
160
155
|
id: peer1,
|
|
161
156
|
remoteId: peer3,
|
|
162
157
|
sessionId: PublicKey.random(),
|
|
@@ -169,7 +164,7 @@ describe('MessageRouter', () => {
|
|
|
169
164
|
}, 4_000);
|
|
170
165
|
|
|
171
166
|
// sending signal from peer2 to peer3.
|
|
172
|
-
const msg2to3:
|
|
167
|
+
const msg2to3: SignalMessage = {
|
|
173
168
|
id: peer2,
|
|
174
169
|
remoteId: peer3,
|
|
175
170
|
sessionId: PublicKey.random(),
|
|
@@ -182,7 +177,7 @@ describe('MessageRouter', () => {
|
|
|
182
177
|
}, 4_000);
|
|
183
178
|
|
|
184
179
|
// sending signal from peer3 to peer1.
|
|
185
|
-
const msg3to1:
|
|
180
|
+
const msg3to1: SignalMessage = {
|
|
186
181
|
id: peer3,
|
|
187
182
|
remoteId: peer1,
|
|
188
183
|
sessionId: PublicKey.random(),
|
|
@@ -198,14 +193,14 @@ describe('MessageRouter', () => {
|
|
|
198
193
|
test('two offers', async () => {
|
|
199
194
|
const { api: api1, router: router1 } = await createSignalClientAndMessageRouter(
|
|
200
195
|
{
|
|
201
|
-
signalApiUrl:
|
|
196
|
+
signalApiUrl: broker1.url(),
|
|
202
197
|
onSignal: (async () => { }) as any,
|
|
203
198
|
onOffer:
|
|
204
199
|
async () => ({ accept: true })
|
|
205
200
|
});
|
|
206
201
|
const { api: api2, router: router2 } = await createSignalClientAndMessageRouter(
|
|
207
202
|
{
|
|
208
|
-
signalApiUrl:
|
|
203
|
+
signalApiUrl: broker1.url(),
|
|
209
204
|
onSignal: (async () => { }) as any,
|
|
210
205
|
onOffer:
|
|
211
206
|
async () => ({ accept: true })
|
|
@@ -242,9 +237,9 @@ describe('MessageRouter', () => {
|
|
|
242
237
|
// Imitates signal network disruptions (e. g. message doubling, ).
|
|
243
238
|
messageDisruption = msg => [msg]
|
|
244
239
|
}: {
|
|
245
|
-
onSignal1?: (msg:
|
|
246
|
-
onSignal2?: (msg:
|
|
247
|
-
messageDisruption?: (msg:
|
|
240
|
+
onSignal1?: (msg: SignalMessage) => Promise<void>;
|
|
241
|
+
onSignal2?: (msg: SignalMessage) => Promise<void>;
|
|
242
|
+
messageDisruption?: (msg: SignalMessage) => SignalMessage[];
|
|
248
243
|
}): {mr1: MessageRouter; mr2: MessageRouter} => {
|
|
249
244
|
|
|
250
245
|
const mr1: MessageRouter = new MessageRouter({
|
|
@@ -268,7 +263,7 @@ describe('MessageRouter', () => {
|
|
|
268
263
|
// Simulate unreliable connection.
|
|
269
264
|
// Only each 3rd message is sent.
|
|
270
265
|
let i = 0;
|
|
271
|
-
const unreliableConnection = (msg:
|
|
266
|
+
const unreliableConnection = (msg: SignalMessage): SignalMessage[] => {
|
|
272
267
|
i++;
|
|
273
268
|
if (i % 3 !== 0) {
|
|
274
269
|
return [msg];
|
|
@@ -276,8 +271,8 @@ describe('MessageRouter', () => {
|
|
|
276
271
|
return [];
|
|
277
272
|
};
|
|
278
273
|
|
|
279
|
-
const received:
|
|
280
|
-
const signalMock1 = async (msg:
|
|
274
|
+
const received: SignalMessage[] = [];
|
|
275
|
+
const signalMock1 = async (msg: SignalMessage) => {
|
|
281
276
|
received.push(msg);
|
|
282
277
|
};
|
|
283
278
|
|
|
@@ -294,7 +289,7 @@ describe('MessageRouter', () => {
|
|
|
294
289
|
remoteId: PublicKey.random(),
|
|
295
290
|
sessionId: PublicKey.random(),
|
|
296
291
|
topic: PublicKey.random(),
|
|
297
|
-
data: { signal: { json: 'asd' } }
|
|
292
|
+
data: { signal: { json: JSON.stringify({ 'asd': 'asd' }) } }
|
|
298
293
|
});
|
|
299
294
|
});
|
|
300
295
|
// expect to receive 3 messages.
|
|
@@ -305,10 +300,10 @@ describe('MessageRouter', () => {
|
|
|
305
300
|
|
|
306
301
|
test('ignoring doubled messages', async () => {
|
|
307
302
|
// Message got doubled going through signal network.
|
|
308
|
-
const doublingMessage = (msg:
|
|
303
|
+
const doublingMessage = (msg: SignalMessage) => [msg, msg];
|
|
309
304
|
|
|
310
|
-
const received:
|
|
311
|
-
const signalMock1 = async (msg:
|
|
305
|
+
const received: SignalMessage[] = [];
|
|
306
|
+
const signalMock1 = async (msg: SignalMessage) => {
|
|
312
307
|
received.push(msg);
|
|
313
308
|
};
|
|
314
309
|
|
|
@@ -8,7 +8,7 @@ import debug from 'debug';
|
|
|
8
8
|
import { PublicKey } from '@dxos/protocols';
|
|
9
9
|
import { ComplexMap, ComplexSet, exponentialBackoffInterval, SubscriptionGroup } from '@dxos/util';
|
|
10
10
|
|
|
11
|
-
import { Answer,
|
|
11
|
+
import { Answer, SignalMessage } from '../proto/gen/dxos/mesh/signalMessage';
|
|
12
12
|
import { SignalMessaging } from './signal-manager';
|
|
13
13
|
|
|
14
14
|
interface OfferRecord {
|
|
@@ -17,9 +17,9 @@ interface OfferRecord {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
interface MessageRouterOptions {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
sendMessage?: (message: SignalMessage) => Promise<void>;
|
|
21
|
+
onOffer?: (message: SignalMessage) => Promise<Answer>;
|
|
22
|
+
onSignal?: (message: SignalMessage) => Promise<void>;
|
|
23
23
|
retryDelay?: number;
|
|
24
24
|
timeout?: number;
|
|
25
25
|
}
|
|
@@ -31,9 +31,9 @@ const log = debug('dxos:network-manager:message-router');
|
|
|
31
31
|
// TODO(mykola): https://github.com/dxos/protocols/issues/1316
|
|
32
32
|
export class MessageRouter implements SignalMessaging {
|
|
33
33
|
private readonly _offerRecords: ComplexMap<PublicKey, OfferRecord> = new ComplexMap(key => key.toHex());
|
|
34
|
-
private readonly _onSignal: (message:
|
|
35
|
-
private readonly _sendMessage: (message:
|
|
36
|
-
private readonly _onOffer: (message:
|
|
34
|
+
private readonly _onSignal: (message: SignalMessage) => Promise<void>;
|
|
35
|
+
private readonly _sendMessage: (message: SignalMessage) => Promise<void>;
|
|
36
|
+
private readonly _onOffer: (message: SignalMessage) => Promise<Answer>;
|
|
37
37
|
|
|
38
38
|
private readonly _onAckCallbacks = new ComplexMap<PublicKey, () => void>(key => key.toHex());
|
|
39
39
|
private readonly _receivedMessages = new ComplexSet<PublicKey>(key => key.toHex());
|
|
@@ -59,7 +59,7 @@ export class MessageRouter implements SignalMessaging {
|
|
|
59
59
|
this._timeout = timeout;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
async receiveMessage (message:
|
|
62
|
+
async receiveMessage (message: SignalMessage): Promise<void> {
|
|
63
63
|
log(`receive message: ${JSON.stringify(message)}`);
|
|
64
64
|
if (!message.data?.ack) {
|
|
65
65
|
if (this._receivedMessages.has(message.messageId!)) {
|
|
@@ -81,12 +81,12 @@ export class MessageRouter implements SignalMessaging {
|
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
async signal (message:
|
|
84
|
+
async signal (message: SignalMessage): Promise<void> {
|
|
85
85
|
assert(message.data?.signal);
|
|
86
86
|
await this._sendReliableMessage(message);
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
async offer (message:
|
|
89
|
+
async offer (message: SignalMessage): Promise<Answer> {
|
|
90
90
|
message.messageId = PublicKey.random();
|
|
91
91
|
const promise = new Promise<Answer>((resolve, reject) => {
|
|
92
92
|
this._offerRecords.set(message.messageId!, { resolve, reject });
|
|
@@ -95,7 +95,7 @@ export class MessageRouter implements SignalMessaging {
|
|
|
95
95
|
return promise;
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
private async _sendReliableMessage (message:
|
|
98
|
+
private async _sendReliableMessage (message: SignalMessage): Promise<PublicKey> {
|
|
99
99
|
// Setting unique messageId if it not specified yet.
|
|
100
100
|
message.messageId = message.messageId ?? PublicKey.random();
|
|
101
101
|
log(`sent message: ${JSON.stringify(message)}`);
|
|
@@ -103,7 +103,11 @@ export class MessageRouter implements SignalMessaging {
|
|
|
103
103
|
// Setting retry interval if signal was not acknowledged.
|
|
104
104
|
const cancelRetry = exponentialBackoffInterval(async () => {
|
|
105
105
|
log(`retrying message: ${JSON.stringify(message)}`);
|
|
106
|
-
|
|
106
|
+
try {
|
|
107
|
+
await this._sendMessage(message);
|
|
108
|
+
} catch (error) {
|
|
109
|
+
log(`ERROR failed to send message: ${error}`);
|
|
110
|
+
}
|
|
107
111
|
}, this._retryDelay);
|
|
108
112
|
|
|
109
113
|
const timeout = setTimeout(() => {
|
|
@@ -125,7 +129,7 @@ export class MessageRouter implements SignalMessaging {
|
|
|
125
129
|
return message.messageId;
|
|
126
130
|
}
|
|
127
131
|
|
|
128
|
-
private async _resolveAnswers (message:
|
|
132
|
+
private async _resolveAnswers (message: SignalMessage): Promise<void> {
|
|
129
133
|
assert(message.data?.answer?.offerMessageId, 'No offerMessageId');
|
|
130
134
|
const offerRecord = this._offerRecords.get(message.data.answer.offerMessageId);
|
|
131
135
|
if (offerRecord) {
|
|
@@ -136,10 +140,10 @@ export class MessageRouter implements SignalMessaging {
|
|
|
136
140
|
}
|
|
137
141
|
}
|
|
138
142
|
|
|
139
|
-
private async _handleOffer (message:
|
|
143
|
+
private async _handleOffer (message: SignalMessage): Promise<void> {
|
|
140
144
|
const answer = await this._onOffer(message);
|
|
141
145
|
answer.offerMessageId = message.messageId;
|
|
142
|
-
const answerMessage:
|
|
146
|
+
const answerMessage: SignalMessage = {
|
|
143
147
|
id: message.remoteId,
|
|
144
148
|
remoteId: message.id,
|
|
145
149
|
topic: message.topic,
|
|
@@ -149,17 +153,17 @@ export class MessageRouter implements SignalMessaging {
|
|
|
149
153
|
await this._sendReliableMessage(answerMessage);
|
|
150
154
|
}
|
|
151
155
|
|
|
152
|
-
private async _handleSignal (message:
|
|
156
|
+
private async _handleSignal (message: SignalMessage): Promise<void> {
|
|
153
157
|
assert(message.messageId);
|
|
154
158
|
await this._onSignal(message);
|
|
155
159
|
}
|
|
156
160
|
|
|
157
|
-
private async _handleAcknowledgement (message:
|
|
161
|
+
private async _handleAcknowledgement (message: SignalMessage): Promise<void> {
|
|
158
162
|
assert(message.data?.ack?.messageId);
|
|
159
163
|
this._onAckCallbacks.get(message.data.ack.messageId)?.();
|
|
160
164
|
}
|
|
161
165
|
|
|
162
|
-
private async _sendAcknowledgement (message:
|
|
166
|
+
private async _sendAcknowledgement (message: SignalMessage): Promise<void> {
|
|
163
167
|
assert(message.messageId);
|
|
164
168
|
const ackMessage = {
|
|
165
169
|
id: message.remoteId,
|
|
@@ -6,166 +6,144 @@ import { expect, mockFn } from 'earljs';
|
|
|
6
6
|
import { it as test, describe } from 'mocha';
|
|
7
7
|
import waitForExpect from 'wait-for-expect';
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import { sleep } from '@dxos/async';
|
|
10
10
|
import { PublicKey } from '@dxos/protocols';
|
|
11
|
-
import { createTestBroker } from '@dxos/signal';
|
|
12
|
-
import {
|
|
11
|
+
import { createTestBroker, TestBroker } from '@dxos/signal';
|
|
12
|
+
import { afterTest } from '@dxos/testutils';
|
|
13
13
|
|
|
14
|
-
import {
|
|
14
|
+
import { SignalMessage } from '../proto/gen/dxos/mesh/signalMessage';
|
|
15
15
|
import { SignalClient } from './signal-client';
|
|
16
16
|
|
|
17
|
-
describe('
|
|
18
|
-
let
|
|
19
|
-
let peer1: PublicKey;
|
|
20
|
-
let peer2: PublicKey;
|
|
21
|
-
let api1: SignalClient;
|
|
22
|
-
let api2: SignalClient;
|
|
17
|
+
describe('SignalClient', () => {
|
|
18
|
+
let broker1: TestBroker;
|
|
23
19
|
|
|
24
|
-
let
|
|
25
|
-
const signalApiPort1 = randomInt(10000, 50000);
|
|
26
|
-
const signalApiUrl1 = 'http://0.0.0.0:' + signalApiPort1;
|
|
27
|
-
|
|
28
|
-
// code let broker2: ReturnType<typeof createBroker>;
|
|
29
|
-
const signalApiPort2 = randomInt(10000, 50000);
|
|
30
|
-
const signalApiUrl2 = 'http://0.0.0.0:' + signalApiPort2;
|
|
20
|
+
let broker2: TestBroker;
|
|
31
21
|
|
|
32
22
|
before(async () => {
|
|
33
|
-
broker1 = await createTestBroker(
|
|
34
|
-
// broker2 = await createTestBroker(signalApiPort2);
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
beforeEach(() => {
|
|
38
|
-
topic = PublicKey.random();
|
|
39
|
-
peer1 = PublicKey.random();
|
|
40
|
-
peer2 = PublicKey.random();
|
|
23
|
+
broker1 = await createTestBroker();
|
|
24
|
+
// broker2 = await await createTestBroker(signalApiPort2);
|
|
41
25
|
});
|
|
42
26
|
|
|
43
|
-
after(
|
|
44
|
-
|
|
45
|
-
await api1.close();
|
|
46
|
-
await broker1.stop();
|
|
27
|
+
after(() => {
|
|
28
|
+
broker1.stop();
|
|
47
29
|
// code await broker2.stop();
|
|
48
30
|
});
|
|
49
31
|
|
|
50
32
|
test('message between 2 clients', async () => {
|
|
51
|
-
const
|
|
33
|
+
const topic = PublicKey.random();
|
|
34
|
+
const peer1 = PublicKey.random();
|
|
35
|
+
const peer2 = PublicKey.random();
|
|
36
|
+
const signalMock1 = mockFn<(msg: SignalMessage) => Promise<void>>()
|
|
52
37
|
.resolvesTo();
|
|
53
|
-
api1 = new SignalClient(
|
|
54
|
-
|
|
38
|
+
const api1 = new SignalClient(broker1.url(), signalMock1);
|
|
39
|
+
afterTest(() => api1.close());
|
|
40
|
+
const api2 = new SignalClient(broker1.url(), (async () => {}) as any);
|
|
41
|
+
afterTest(() => api2.close());
|
|
55
42
|
|
|
56
43
|
await api1.join(topic, peer1);
|
|
57
44
|
await api2.join(topic, peer2);
|
|
58
45
|
|
|
59
|
-
const msg:
|
|
46
|
+
const msg: SignalMessage = {
|
|
60
47
|
id: peer2,
|
|
61
48
|
remoteId: peer1,
|
|
62
49
|
sessionId: PublicKey.random(),
|
|
63
50
|
topic,
|
|
64
|
-
data: { signal: { json:
|
|
65
|
-
messageId: undefined
|
|
51
|
+
data: { signal: { json: JSON.stringify({ 'asd': 'asd' }) } }
|
|
66
52
|
};
|
|
67
53
|
await api2.signal(msg);
|
|
68
|
-
|
|
69
54
|
await waitForExpect(() => {
|
|
70
55
|
expect(signalMock1).toHaveBeenCalledWith([msg]);
|
|
71
56
|
}, 4_000);
|
|
72
|
-
}).timeout(
|
|
57
|
+
}).timeout(500);
|
|
73
58
|
|
|
74
59
|
test('join', async () => {
|
|
75
|
-
|
|
60
|
+
const topic = PublicKey.random();
|
|
61
|
+
const peer1 = PublicKey.random();
|
|
62
|
+
const peer2 = PublicKey.random();
|
|
63
|
+
const api1 = new SignalClient(broker1.url(), async () => {});
|
|
64
|
+
afterTest(() => api1.close());
|
|
65
|
+
const api2 = new SignalClient(broker1.url(), async () => {});
|
|
66
|
+
afterTest(() => api2.close());
|
|
76
67
|
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const join2 = await api1.join(topic, peer2);
|
|
81
|
-
expect(join2).toEqual([peer1, peer2]);
|
|
82
|
-
}).timeout(1_000);
|
|
83
|
-
|
|
84
|
-
test('offer', async () => {
|
|
85
|
-
const offerMock = mockFn<(msg: Message) => Promise<Answer>>()
|
|
86
|
-
.resolvesTo({ accept: true });
|
|
87
|
-
api1 = new SignalClient(signalApiUrl1, offerMock, async () => {});
|
|
68
|
+
const promise1 = api1.swarmEvent.waitFor(([, swarmEvent]) => !!swarmEvent.peerAvailable && peer2.equals(swarmEvent.peerAvailable.peer));
|
|
69
|
+
const promise2 = api2.swarmEvent.waitFor(([, swarmEvent]) => !!swarmEvent.peerAvailable && peer1.equals(swarmEvent.peerAvailable.peer));
|
|
88
70
|
|
|
89
71
|
await api1.join(topic, peer1);
|
|
72
|
+
await api2.join(topic, peer2);
|
|
90
73
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
remoteId: peer1,
|
|
95
|
-
sessionId: PublicKey.random(),
|
|
96
|
-
topic
|
|
97
|
-
};
|
|
98
|
-
const offerResult = await api1.offer(offer);
|
|
99
|
-
expect(offerResult).toEqual({ accept: true });
|
|
100
|
-
expect(offerMock).toHaveBeenCalledWith([offer]);
|
|
101
|
-
}).timeout(5_000);
|
|
74
|
+
await promise1;
|
|
75
|
+
await promise2;
|
|
76
|
+
}).timeout(500);
|
|
102
77
|
|
|
103
|
-
test('signal', async () => {
|
|
104
|
-
const
|
|
78
|
+
test('signal to self', async () => {
|
|
79
|
+
const topic = PublicKey.random();
|
|
80
|
+
const peer1 = PublicKey.random();
|
|
81
|
+
const peer2 = PublicKey.random();
|
|
82
|
+
const signalMock = mockFn<(msg: SignalMessage) => Promise<void>>()
|
|
105
83
|
.resolvesTo();
|
|
106
|
-
api1 = new SignalClient(
|
|
84
|
+
const api1 = new SignalClient(broker1.url(), signalMock);
|
|
85
|
+
afterTest(() => api1.close());
|
|
107
86
|
|
|
108
87
|
await api1.join(topic, peer1);
|
|
109
88
|
|
|
110
|
-
const msg:
|
|
89
|
+
const msg: SignalMessage = {
|
|
111
90
|
id: peer2,
|
|
112
91
|
remoteId: peer1,
|
|
113
92
|
sessionId: PublicKey.random(),
|
|
114
93
|
topic,
|
|
115
|
-
data: { signal: { json: '
|
|
116
|
-
messageId: undefined
|
|
94
|
+
data: { signal: { json: JSON.stringify({ 'asd': 'asd' }) } }
|
|
117
95
|
};
|
|
118
96
|
await api1.signal(msg);
|
|
119
97
|
|
|
120
98
|
await waitForExpect(() => {
|
|
121
99
|
expect(signalMock).toHaveBeenCalledWith([msg]);
|
|
122
100
|
}, 4_000);
|
|
123
|
-
}).timeout(
|
|
101
|
+
}).timeout(500);
|
|
124
102
|
|
|
125
103
|
test.skip('join across multiple signal servers', async () => {
|
|
104
|
+
const topic = PublicKey.random();
|
|
105
|
+
const peer1 = PublicKey.random();
|
|
106
|
+
const peer2 = PublicKey.random();
|
|
126
107
|
// This feature is not implemented yet.
|
|
127
|
-
api1 = new SignalClient(
|
|
128
|
-
|
|
108
|
+
const api1 = new SignalClient(broker1.url(), async () => {});
|
|
109
|
+
afterTest(() => api1.close());
|
|
110
|
+
const api2 = new SignalClient(broker2.url(), async () => {});
|
|
111
|
+
afterTest(() => api2.close());
|
|
129
112
|
|
|
130
113
|
await api1.join(topic, peer1);
|
|
131
114
|
await api2.join(topic, peer2);
|
|
132
115
|
|
|
133
|
-
await waitForExpect(async () => {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}, 4_000);
|
|
116
|
+
// await waitForExpect(async () => {
|
|
117
|
+
// const peers = await api2.lookup(topic);
|
|
118
|
+
// expect(peers.length).toEqual(2);
|
|
119
|
+
// }, 4_000);
|
|
137
120
|
|
|
138
|
-
await waitForExpect(async () => {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}, 4_000);
|
|
121
|
+
// await waitForExpect(async () => {
|
|
122
|
+
// const peers = await api1.lookup(topic);
|
|
123
|
+
// expect(peers.length).toEqual(2);
|
|
124
|
+
// }, 4_000);
|
|
142
125
|
}).timeout(5_000);
|
|
143
126
|
|
|
144
127
|
// Skip because communication between signal servers is not yet implemented.
|
|
145
128
|
test.skip('newly joined peer can receive signals from other signal servers', async () => {
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
const
|
|
129
|
+
const topic = PublicKey.random();
|
|
130
|
+
const peer1 = PublicKey.random();
|
|
131
|
+
const peer2 = PublicKey.random();
|
|
132
|
+
const signalMock = mockFn<(msg: SignalMessage) => Promise<void>>()
|
|
149
133
|
.resolvesTo();
|
|
150
134
|
|
|
151
|
-
api1 = new SignalClient(
|
|
152
|
-
|
|
135
|
+
const api1 = new SignalClient(broker1.url(), async () => {});
|
|
136
|
+
afterTest(() => api1.close());
|
|
137
|
+
const api2 = new SignalClient(broker2.url(), signalMock);
|
|
138
|
+
afterTest(() => api2.close());
|
|
153
139
|
|
|
154
140
|
await api1.join(topic, peer1);
|
|
155
141
|
await sleep(3000);
|
|
156
142
|
await api2.join(topic, peer2);
|
|
157
143
|
|
|
158
144
|
const sessionId = PublicKey.random();
|
|
159
|
-
const answer = await api2.offer({
|
|
160
|
-
remoteId: peer1,
|
|
161
|
-
id: peer2,
|
|
162
|
-
topic,
|
|
163
|
-
sessionId,
|
|
164
|
-
data: { offer: {} }
|
|
165
|
-
});
|
|
166
|
-
expect(answer).toEqual({ accept: true });
|
|
167
145
|
|
|
168
|
-
const msg:
|
|
146
|
+
const msg: SignalMessage = {
|
|
169
147
|
id: peer2,
|
|
170
148
|
remoteId: peer1,
|
|
171
149
|
sessionId,
|
|
@@ -178,4 +156,4 @@ describe('SignalApi', () => {
|
|
|
178
156
|
expect(signalMock).toHaveBeenCalledWith([msg]);
|
|
179
157
|
}, 4_000);
|
|
180
158
|
}).timeout(5_000);
|
|
181
|
-
})
|
|
159
|
+
});
|