@dxos/network-manager 0.1.2 → 0.1.4
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/connection-log.d.ts +1 -1
- package/dist/src/connection-log.d.ts.map +1 -1
- package/dist/src/network-manager.test.js +10 -13
- package/dist/src/network-manager.test.js.map +1 -1
- package/dist/src/swarm/connection.d.ts.map +1 -1
- package/dist/src/swarm/connection.js +14 -10
- package/dist/src/swarm/connection.js.map +1 -1
- package/dist/src/transport/memory-transport.d.ts +6 -13
- package/dist/src/transport/memory-transport.d.ts.map +1 -1
- package/dist/src/transport/memory-transport.js +41 -35
- package/dist/src/transport/memory-transport.js.map +1 -1
- package/dist/src/transport/memory-transport.test.js +14 -3
- package/dist/src/transport/memory-transport.test.js.map +1 -1
- package/dist/src/transport/transport.d.ts +1 -7
- package/dist/src/transport/transport.d.ts.map +1 -1
- package/dist/src/transport/webrtc-transport-proxy.d.ts +3 -9
- package/dist/src/transport/webrtc-transport-proxy.d.ts.map +1 -1
- package/dist/src/transport/webrtc-transport-proxy.js +12 -17
- package/dist/src/transport/webrtc-transport-proxy.js.map +1 -1
- package/dist/src/transport/webrtc-transport-proxy.test.js +14 -40
- package/dist/src/transport/webrtc-transport-proxy.test.js.map +1 -1
- package/dist/src/transport/webrtc-transport-service.d.ts +1 -4
- package/dist/src/transport/webrtc-transport-service.d.ts.map +1 -1
- package/dist/src/transport/webrtc-transport-service.js +32 -36
- package/dist/src/transport/webrtc-transport-service.js.map +1 -1
- package/dist/src/transport/webrtc-transport.d.ts +8 -13
- package/dist/src/transport/webrtc-transport.d.ts.map +1 -1
- package/dist/src/transport/webrtc-transport.js +18 -44
- package/dist/src/transport/webrtc-transport.js.map +1 -1
- package/dist/src/transport/webrtc-transport.test.js +25 -14
- package/dist/src/transport/webrtc-transport.test.js.map +1 -1
- package/package.json +16 -16
- package/src/connection-log.ts +1 -1
- package/src/network-manager.test.ts +0 -3
- package/src/swarm/connection.ts +9 -5
- package/src/transport/memory-transport.test.ts +14 -15
- package/src/transport/memory-transport.ts +48 -49
- package/src/transport/transport.ts +1 -9
- package/src/transport/webrtc-transport-proxy.test.ts +16 -51
- package/src/transport/webrtc-transport-proxy.ts +13 -23
- package/src/transport/webrtc-transport-service.ts +34 -39
- package/src/transport/webrtc-transport.test.ts +17 -30
- package/src/transport/webrtc-transport.ts +22 -54
|
@@ -19,7 +19,11 @@ const webrtc_transport_1 = require("./webrtc-transport");
|
|
|
19
19
|
describe('WebRTCTransport', function () {
|
|
20
20
|
// This doesn't clean up correctly and crashes with SIGSEGV / SIGABRT at the end. Probably an issue with wrtc package.
|
|
21
21
|
it('open and close', async function () {
|
|
22
|
-
const connection = new webrtc_transport_1.WebRTCTransport(
|
|
22
|
+
const connection = new webrtc_transport_1.WebRTCTransport({
|
|
23
|
+
initiator: true,
|
|
24
|
+
stream: new stream_1.Duplex(),
|
|
25
|
+
sendSignal: async () => { }
|
|
26
|
+
});
|
|
23
27
|
let callsCounter = 0;
|
|
24
28
|
const closedCb = () => {
|
|
25
29
|
callsCounter++;
|
|
@@ -36,26 +40,33 @@ describe('WebRTCTransport', function () {
|
|
|
36
40
|
const topic = keys_1.PublicKey.random();
|
|
37
41
|
const peer1Id = keys_1.PublicKey.random();
|
|
38
42
|
const peer2Id = keys_1.PublicKey.random();
|
|
39
|
-
const sessionId = keys_1.PublicKey.random();
|
|
40
43
|
const plugin1 = new testing_1.TestProtocolPlugin(peer1Id.asBuffer());
|
|
41
44
|
const protocolProvider1 = (0, testing_1.testProtocolProvider)(topic.asBuffer(), peer1Id.asBuffer(), plugin1);
|
|
42
|
-
const connection1 = new webrtc_transport_1.WebRTCTransport(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
const connection1 = new webrtc_transport_1.WebRTCTransport({
|
|
46
|
+
initiator: true,
|
|
47
|
+
stream: protocolProvider1({
|
|
48
|
+
channel: (0, crypto_1.discoveryKey)(topic),
|
|
49
|
+
initiator: true
|
|
50
|
+
}).stream,
|
|
51
|
+
sendSignal: async (signal) => {
|
|
52
|
+
await (0, async_1.sleep)(10);
|
|
53
|
+
await connection2.signal(signal);
|
|
54
|
+
}
|
|
48
55
|
});
|
|
49
56
|
(0, testutils_1.afterTest)(() => connection1.close());
|
|
50
57
|
(0, testutils_1.afterTest)(() => connection1.errors.assertNoUnhandledErrors());
|
|
51
58
|
const plugin2 = new testing_1.TestProtocolPlugin(peer2Id.asBuffer());
|
|
52
59
|
const protocolProvider2 = (0, testing_1.testProtocolProvider)(topic.asBuffer(), peer2Id.asBuffer(), plugin2);
|
|
53
|
-
const connection2 = new webrtc_transport_1.WebRTCTransport(
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
60
|
+
const connection2 = new webrtc_transport_1.WebRTCTransport({
|
|
61
|
+
initiator: false,
|
|
62
|
+
stream: protocolProvider2({
|
|
63
|
+
channel: (0, crypto_1.discoveryKey)(topic),
|
|
64
|
+
initiator: false
|
|
65
|
+
}).stream,
|
|
66
|
+
sendSignal: async (signal) => {
|
|
67
|
+
await (0, async_1.sleep)(10);
|
|
68
|
+
await connection1.signal(signal);
|
|
69
|
+
}
|
|
59
70
|
});
|
|
60
71
|
(0, testutils_1.afterTest)(() => connection2.close());
|
|
61
72
|
(0, testutils_1.afterTest)(() => connection2.errors.assertNoUnhandledErrors());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webrtc-transport.test.js","sourceRoot":"","sources":["../../../src/transport/webrtc-transport.test.ts"],"names":[],"mappings":";AAAA,EAAE;AACF,0BAA0B;AAC1B,EAAE;;;;;AAEF,oDAA4B;AAC5B,mCAAgC;AAChC,sEAA4C;AAE5C,uCAAoC;AACpC,yCAA4C;AAC5C,qCAAuC;AACvC,uDAA+C;AAC/C,+CAA4C;AAE5C,wCAAsE;AACtE,yDAAqD;AAErD,QAAQ,CAAC,iBAAiB,EAAE;IAC1B,sHAAsH;IACtH,EAAE,CAAC,gBAAgB,EAAE,KAAK;QACxB,MAAM,UAAU,GAAG,IAAI,kCAAe,
|
|
1
|
+
{"version":3,"file":"webrtc-transport.test.js","sourceRoot":"","sources":["../../../src/transport/webrtc-transport.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/network-manager",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Network Manager",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -17,19 +17,19 @@
|
|
|
17
17
|
"README.md"
|
|
18
18
|
],
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@dxos/async": "0.1.
|
|
21
|
-
"@dxos/codec-protobuf": "0.1.
|
|
22
|
-
"@dxos/credentials": "0.1.
|
|
23
|
-
"@dxos/crypto": "0.1.
|
|
24
|
-
"@dxos/debug": "0.1.
|
|
25
|
-
"@dxos/keys": "0.1.
|
|
26
|
-
"@dxos/log": "0.1.
|
|
27
|
-
"@dxos/mesh-protocol": "0.1.
|
|
28
|
-
"@dxos/messaging": "0.1.
|
|
29
|
-
"@dxos/protocol-plugin-presence": "0.1.
|
|
30
|
-
"@dxos/protocols": "0.1.
|
|
31
|
-
"@dxos/rpc": "0.1.
|
|
32
|
-
"@dxos/util": "0.1.
|
|
20
|
+
"@dxos/async": "0.1.4",
|
|
21
|
+
"@dxos/codec-protobuf": "0.1.4",
|
|
22
|
+
"@dxos/credentials": "0.1.4",
|
|
23
|
+
"@dxos/crypto": "0.1.4",
|
|
24
|
+
"@dxos/debug": "0.1.4",
|
|
25
|
+
"@dxos/keys": "0.1.4",
|
|
26
|
+
"@dxos/log": "0.1.4",
|
|
27
|
+
"@dxos/mesh-protocol": "0.1.4",
|
|
28
|
+
"@dxos/messaging": "0.1.4",
|
|
29
|
+
"@dxos/protocol-plugin-presence": "0.1.4",
|
|
30
|
+
"@dxos/protocols": "0.1.4",
|
|
31
|
+
"@dxos/rpc": "0.1.4",
|
|
32
|
+
"@dxos/util": "0.1.4",
|
|
33
33
|
"@koush/wrtc": "^0.5.3",
|
|
34
34
|
"assert": "^2.0.0",
|
|
35
35
|
"isomorphic-ws": "^4.0.1",
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
"xor-distance": "^2.0.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@dxos/signal": "0.1.
|
|
43
|
-
"@dxos/testutils": "0.1.
|
|
42
|
+
"@dxos/signal": "0.1.4",
|
|
43
|
+
"@dxos/testutils": "0.1.4",
|
|
44
44
|
"@swc-node/register": "^1.5.4",
|
|
45
45
|
"@swc/core": "^1.3.9",
|
|
46
46
|
"@types/simple-peer": "9.11.3",
|
package/src/connection-log.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { Event } from '@dxos/async';
|
|
6
6
|
import { raise } from '@dxos/debug';
|
|
7
7
|
import { PublicKey } from '@dxos/keys';
|
|
8
|
-
import { SwarmInfo, ConnectionInfo } from '@dxos/protocols/proto/dxos/devtools/
|
|
8
|
+
import { SwarmInfo, ConnectionInfo } from '@dxos/protocols/proto/dxos/devtools/swarm';
|
|
9
9
|
import { ComplexMap } from '@dxos/util';
|
|
10
10
|
|
|
11
11
|
import { ConnectionState, Swarm } from './swarm';
|
|
@@ -203,7 +203,6 @@ describe('NetworkManager', function () {
|
|
|
203
203
|
|
|
204
204
|
const webRTCTransportService: BridgeService = new WebRTCTransportService();
|
|
205
205
|
const service = createProtoRpcPeer({
|
|
206
|
-
requested: {},
|
|
207
206
|
exposed: {
|
|
208
207
|
BridgeService: schema.getService('dxos.mesh.bridge.BridgeService')
|
|
209
208
|
},
|
|
@@ -219,8 +218,6 @@ describe('NetworkManager', function () {
|
|
|
219
218
|
requested: {
|
|
220
219
|
BridgeService: schema.getService('dxos.mesh.bridge.BridgeService')
|
|
221
220
|
},
|
|
222
|
-
exposed: {},
|
|
223
|
-
handlers: {},
|
|
224
221
|
port: rpcPortB,
|
|
225
222
|
noHandshake: true,
|
|
226
223
|
encodingOptions: {
|
package/src/swarm/connection.ts
CHANGED
|
@@ -131,13 +131,17 @@ export class Connection {
|
|
|
131
131
|
|
|
132
132
|
assert(!this._transport);
|
|
133
133
|
this._transport = this._transportFactory.create({
|
|
134
|
-
topic: this.topic,
|
|
135
|
-
ownId: this.ownId,
|
|
136
|
-
remoteId: this.remoteId,
|
|
137
|
-
sessionId: this.sessionId,
|
|
138
134
|
initiator: this.initiator,
|
|
139
135
|
stream: this._protocol.stream,
|
|
140
|
-
sendSignal:
|
|
136
|
+
sendSignal: async (signal) => {
|
|
137
|
+
await this._signalMessaging.signal({
|
|
138
|
+
author: this.ownId,
|
|
139
|
+
recipient: this.remoteId,
|
|
140
|
+
sessionId: this.sessionId,
|
|
141
|
+
topic: this.topic,
|
|
142
|
+
data: { signal }
|
|
143
|
+
});
|
|
144
|
+
}
|
|
141
145
|
});
|
|
142
146
|
|
|
143
147
|
this._transport.connected.once(() => {
|
|
@@ -22,30 +22,29 @@ const createPair = () => {
|
|
|
22
22
|
const topic = PublicKey.random();
|
|
23
23
|
const peer1Id = PublicKey.random();
|
|
24
24
|
const peer2Id = PublicKey.random();
|
|
25
|
-
const sessionId = PublicKey.random();
|
|
26
25
|
|
|
27
26
|
const plugin1 = new TestProtocolPlugin(peer1Id.asBuffer());
|
|
28
27
|
const protocolProvider1 = testProtocolProvider(topic.asBuffer(), peer1Id.asBuffer(), plugin1);
|
|
29
|
-
const connection1 = new MemoryTransport(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
);
|
|
28
|
+
const connection1 = new MemoryTransport({
|
|
29
|
+
stream: protocolProvider1({ channel: discoveryKey(topic), initiator: true }).stream,
|
|
30
|
+
sendSignal: async (signal) => {
|
|
31
|
+
await connection2.signal(signal);
|
|
32
|
+
},
|
|
33
|
+
initiator: true
|
|
34
|
+
});
|
|
36
35
|
|
|
37
36
|
afterTest(() => connection1.close());
|
|
38
37
|
afterTest(() => connection1.errors.assertNoUnhandledErrors());
|
|
39
38
|
|
|
40
39
|
const plugin2 = new TestProtocolPlugin(peer2Id.asBuffer());
|
|
41
40
|
const protocolProvider2 = testProtocolProvider(topic.asBuffer(), peer2Id.asBuffer(), plugin2);
|
|
42
|
-
const connection2 = new MemoryTransport(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
);
|
|
41
|
+
const connection2 = new MemoryTransport({
|
|
42
|
+
stream: protocolProvider2({ channel: discoveryKey(topic), initiator: false }).stream,
|
|
43
|
+
sendSignal: async (signal) => {
|
|
44
|
+
await connection1.signal(signal);
|
|
45
|
+
},
|
|
46
|
+
initiator: false
|
|
47
|
+
});
|
|
49
48
|
|
|
50
49
|
afterTest(() => connection2.close());
|
|
51
50
|
afterTest(() => connection2.errors.assertNoUnhandledErrors());
|
|
@@ -5,16 +5,14 @@
|
|
|
5
5
|
import assert from 'node:assert';
|
|
6
6
|
import { Transform } from 'stream';
|
|
7
7
|
|
|
8
|
-
import { Event } from '@dxos/async';
|
|
8
|
+
import { Event, Trigger } from '@dxos/async';
|
|
9
9
|
import { ErrorStream } from '@dxos/debug';
|
|
10
10
|
import { PublicKey } from '@dxos/keys';
|
|
11
11
|
import { log } from '@dxos/log';
|
|
12
12
|
import { Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';
|
|
13
13
|
import { ComplexMap } from '@dxos/util';
|
|
14
14
|
|
|
15
|
-
import { Transport, TransportFactory } from './transport';
|
|
16
|
-
|
|
17
|
-
type ConnectionKey = [topic: PublicKey, nodeId: PublicKey, remoteId: PublicKey];
|
|
15
|
+
import { Transport, TransportFactory, TransportOptions } from './transport';
|
|
18
16
|
|
|
19
17
|
// Delay (in milliseconds) for data being sent through in-memory connections to simulate network latency.
|
|
20
18
|
const MEMORY_TRANSPORT_DELAY = 1;
|
|
@@ -36,71 +34,72 @@ const createStreamDelay = (delay: number): NodeJS.ReadWriteStream =>
|
|
|
36
34
|
// TODO(burdon): Remove static variables.
|
|
37
35
|
export class MemoryTransport implements Transport {
|
|
38
36
|
// TODO(burdon): Remove global properties.
|
|
39
|
-
private static readonly _connections = new ComplexMap<
|
|
40
|
-
([topic, nodeId, remoteId]) => topic.toHex() + nodeId.toHex() + remoteId.toHex()
|
|
41
|
-
);
|
|
37
|
+
private static readonly _connections = new ComplexMap<PublicKey, MemoryTransport>(PublicKey.hash);
|
|
42
38
|
|
|
43
39
|
public readonly closed = new Event<void>();
|
|
44
40
|
public readonly connected = new Event<void>();
|
|
45
41
|
public readonly errors = new ErrorStream();
|
|
46
42
|
|
|
47
|
-
private readonly
|
|
48
|
-
private
|
|
43
|
+
private readonly _ownId = PublicKey.random();
|
|
44
|
+
private _remoteId!: PublicKey;
|
|
45
|
+
private readonly _remote = new Trigger<PublicKey>();
|
|
49
46
|
|
|
50
47
|
private readonly _outgoingDelay = createStreamDelay(MEMORY_TRANSPORT_DELAY);
|
|
51
48
|
private readonly _incomingDelay = createStreamDelay(MEMORY_TRANSPORT_DELAY);
|
|
52
49
|
|
|
53
50
|
private _remoteConnection?: MemoryTransport;
|
|
54
51
|
|
|
55
|
-
constructor(
|
|
56
|
-
|
|
57
|
-
private readonly _remoteId: PublicKey,
|
|
58
|
-
private readonly _sessionId: PublicKey,
|
|
59
|
-
private readonly _topic: PublicKey,
|
|
60
|
-
private readonly _stream: NodeJS.ReadWriteStream
|
|
61
|
-
) {
|
|
62
|
-
log('creating', { topic: this._topic, peerId: this._ownId, remoteId: this._remoteId });
|
|
63
|
-
|
|
64
|
-
this._ownKey = [this._topic, this._ownId, this._remoteId];
|
|
65
|
-
this._remoteKey = [this._topic, this._remoteId, this._ownId];
|
|
66
|
-
|
|
67
|
-
assert(!MemoryTransport._connections.has(this._ownKey), 'Duplicate memory connection');
|
|
68
|
-
MemoryTransport._connections.set(this._ownKey, this);
|
|
69
|
-
|
|
70
|
-
this._remoteConnection = MemoryTransport._connections.get(this._remoteKey);
|
|
71
|
-
if (this._remoteConnection) {
|
|
72
|
-
this._remoteConnection._remoteConnection = this;
|
|
73
|
-
|
|
74
|
-
log('connected', { topic: this._topic, peerId: this._ownId, remoteId: this._remoteId });
|
|
75
|
-
this._stream
|
|
76
|
-
.pipe(this._outgoingDelay)
|
|
77
|
-
.pipe(this._remoteConnection._stream)
|
|
78
|
-
.pipe(this._incomingDelay)
|
|
79
|
-
.pipe(this._stream);
|
|
52
|
+
constructor(private readonly params: TransportOptions) {
|
|
53
|
+
log('creating', this._ownId);
|
|
80
54
|
|
|
81
|
-
|
|
82
|
-
this.
|
|
55
|
+
if (this.params.initiator) {
|
|
56
|
+
setTimeout(async () => this.params.sendSignal({ json: JSON.stringify({ transportId: this._ownId.toHex() }) }));
|
|
83
57
|
}
|
|
84
|
-
}
|
|
85
58
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
59
|
+
assert(!MemoryTransport._connections.has(this._ownId), 'Duplicate memory connection');
|
|
60
|
+
MemoryTransport._connections.set(this._ownId, this);
|
|
61
|
+
|
|
62
|
+
this._remote.wait().then(
|
|
63
|
+
(remoteId) => {
|
|
64
|
+
this._remoteId = remoteId;
|
|
65
|
+
this._remoteConnection = MemoryTransport._connections.get(this._remoteId);
|
|
66
|
+
if (this._remoteConnection) {
|
|
67
|
+
this._remoteConnection._remoteConnection = this;
|
|
68
|
+
this._remoteConnection._remoteId = this._ownId;
|
|
69
|
+
|
|
70
|
+
log('connected', { ownId: this._ownId, remoteId: this._remoteId });
|
|
71
|
+
this.params.stream
|
|
72
|
+
.pipe(this._outgoingDelay)
|
|
73
|
+
.pipe(this._remoteConnection.params.stream)
|
|
74
|
+
.pipe(this._incomingDelay)
|
|
75
|
+
.pipe(this.params.stream);
|
|
76
|
+
|
|
77
|
+
this.connected.emit();
|
|
78
|
+
this._remoteConnection.connected.emit();
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
async (err) => {
|
|
82
|
+
log.catch(err);
|
|
83
|
+
}
|
|
84
|
+
);
|
|
92
85
|
}
|
|
93
86
|
|
|
94
87
|
async signal(signal: Signal) {
|
|
95
|
-
|
|
88
|
+
const { json } = signal;
|
|
89
|
+
if (json) {
|
|
90
|
+
const { transportId } = JSON.parse(json);
|
|
91
|
+
if (transportId) {
|
|
92
|
+
this._remote.wake(PublicKey.from(transportId));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
96
95
|
}
|
|
97
96
|
|
|
98
97
|
async close(): Promise<void> {
|
|
99
|
-
log('closing',
|
|
98
|
+
log('closing', this._ownId);
|
|
100
99
|
|
|
101
|
-
MemoryTransport._connections.delete(this.
|
|
100
|
+
MemoryTransport._connections.delete(this._ownId);
|
|
102
101
|
if (this._remoteConnection) {
|
|
103
|
-
MemoryTransport._connections.delete(this.
|
|
102
|
+
MemoryTransport._connections.delete(this._remoteId);
|
|
104
103
|
|
|
105
104
|
// TODO(dmaretskyi): Hypercore streams do not seem to have the unpipe method.
|
|
106
105
|
// NOTE(burdon): Using readable-stream.wrap() might help (see feed-store).
|
|
@@ -119,10 +118,10 @@ export class MemoryTransport implements Transport {
|
|
|
119
118
|
}
|
|
120
119
|
|
|
121
120
|
this.closed.emit();
|
|
122
|
-
log('closed'
|
|
121
|
+
log('closed');
|
|
123
122
|
}
|
|
124
123
|
}
|
|
125
124
|
|
|
126
125
|
export const MemoryTransportFactory: TransportFactory = {
|
|
127
|
-
create: (
|
|
126
|
+
create: (params) => new MemoryTransport(params)
|
|
128
127
|
};
|
|
@@ -4,11 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
import { Event } from '@dxos/async';
|
|
6
6
|
import { ErrorStream } from '@dxos/debug';
|
|
7
|
-
import { PublicKey } from '@dxos/keys';
|
|
8
7
|
import { Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';
|
|
9
8
|
|
|
10
|
-
import { SignalMessage } from '../signal';
|
|
11
|
-
|
|
12
9
|
/**
|
|
13
10
|
* Abstraction over a P2P connection transport. Currently either WebRTC or in-memory.
|
|
14
11
|
*/
|
|
@@ -26,11 +23,6 @@ export type TransportOptions = {
|
|
|
26
23
|
*/
|
|
27
24
|
initiator: boolean;
|
|
28
25
|
|
|
29
|
-
ownId: PublicKey;
|
|
30
|
-
remoteId: PublicKey;
|
|
31
|
-
sessionId: PublicKey;
|
|
32
|
-
topic: PublicKey;
|
|
33
|
-
|
|
34
26
|
/**
|
|
35
27
|
* Wire protocol.
|
|
36
28
|
*/
|
|
@@ -39,7 +31,7 @@ export type TransportOptions = {
|
|
|
39
31
|
/**
|
|
40
32
|
* Send a signal message to remote peer.
|
|
41
33
|
*/
|
|
42
|
-
sendSignal: (
|
|
34
|
+
sendSignal: (signal: Signal) => Promise<void>; // TODO(burdon): Remove async?
|
|
43
35
|
};
|
|
44
36
|
|
|
45
37
|
export interface TransportFactory {
|
|
@@ -14,10 +14,10 @@ import { PublicKey } from '@dxos/keys';
|
|
|
14
14
|
import { Protocol } from '@dxos/mesh-protocol';
|
|
15
15
|
import { schema } from '@dxos/protocols';
|
|
16
16
|
import { BridgeService } from '@dxos/protocols/proto/dxos/mesh/bridge';
|
|
17
|
+
import { Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';
|
|
17
18
|
import { createLinkedPorts, createProtoRpcPeer, ProtoRpcPeer } from '@dxos/rpc';
|
|
18
19
|
import { afterTest } from '@dxos/testutils';
|
|
19
20
|
|
|
20
|
-
import { SignalMessage } from '../signal';
|
|
21
21
|
import { TestProtocolPlugin, testProtocolProvider } from '../testing';
|
|
22
22
|
import { WebRTCTransportProxy } from './webrtc-transport-proxy';
|
|
23
23
|
import { WebRTCTransportService } from './webrtc-transport-service';
|
|
@@ -25,27 +25,20 @@ import { WebRTCTransportService } from './webrtc-transport-service';
|
|
|
25
25
|
describe('WebRTCTransportProxy', function () {
|
|
26
26
|
const setupProxy = async ({
|
|
27
27
|
initiator = true,
|
|
28
|
-
ownId = PublicKey.random(),
|
|
29
|
-
remoteId = PublicKey.random(),
|
|
30
|
-
sessionId = PublicKey.random(),
|
|
31
|
-
topic = PublicKey.random(),
|
|
32
28
|
stream = new Duplex({ write: () => {}, read: () => {} }),
|
|
33
|
-
sendSignal = () => {}
|
|
29
|
+
sendSignal = async () => {}
|
|
34
30
|
}: {
|
|
35
31
|
initiator?: boolean;
|
|
36
|
-
ownId?: PublicKey;
|
|
37
|
-
remoteId?: PublicKey;
|
|
38
|
-
sessionId?: PublicKey;
|
|
39
|
-
topic?: PublicKey;
|
|
40
32
|
stream?: NodeJS.ReadWriteStream;
|
|
41
|
-
sendSignal?: (msg:
|
|
33
|
+
sendSignal?: (msg: Signal) => Promise<void>;
|
|
42
34
|
} = {}) => {
|
|
43
35
|
const [port1, port2] = createLinkedPorts();
|
|
44
36
|
|
|
37
|
+
// Starting BridgeService
|
|
45
38
|
const webRTCTransportService: BridgeService = new WebRTCTransportService();
|
|
46
39
|
|
|
47
40
|
// Starting BridgeService
|
|
48
|
-
const
|
|
41
|
+
const rpcService = createProtoRpcPeer({
|
|
49
42
|
requested: {},
|
|
50
43
|
exposed: {
|
|
51
44
|
BridgeService: schema.getService('dxos.mesh.bridge.BridgeService')
|
|
@@ -57,16 +50,14 @@ describe('WebRTCTransportProxy', function () {
|
|
|
57
50
|
preserveAny: true
|
|
58
51
|
}
|
|
59
52
|
});
|
|
60
|
-
await
|
|
61
|
-
afterTest(() =>
|
|
53
|
+
await rpcService.open();
|
|
54
|
+
afterTest(() => rpcService.close());
|
|
62
55
|
|
|
63
56
|
// Starting RPC client
|
|
64
57
|
const rpcClient = createProtoRpcPeer({
|
|
65
58
|
requested: {
|
|
66
59
|
BridgeService: schema.getService('dxos.mesh.bridge.BridgeService')
|
|
67
60
|
},
|
|
68
|
-
exposed: {},
|
|
69
|
-
handlers: {},
|
|
70
61
|
port: port2,
|
|
71
62
|
noHandshake: true,
|
|
72
63
|
encodingOptions: {
|
|
@@ -79,16 +70,12 @@ describe('WebRTCTransportProxy', function () {
|
|
|
79
70
|
const webRTCTransportProxy = new WebRTCTransportProxy({
|
|
80
71
|
initiator,
|
|
81
72
|
stream,
|
|
82
|
-
ownId,
|
|
83
|
-
remoteId,
|
|
84
|
-
sessionId,
|
|
85
|
-
topic,
|
|
86
73
|
sendSignal,
|
|
87
74
|
bridgeService: rpcClient.rpc.BridgeService
|
|
88
75
|
});
|
|
89
76
|
afterTest(async () => await webRTCTransportProxy.close());
|
|
90
77
|
|
|
91
|
-
return { webRTCService, webRTCTransportProxy };
|
|
78
|
+
return { webRTCService: rpcService, webRTCTransportProxy };
|
|
92
79
|
};
|
|
93
80
|
|
|
94
81
|
// This doesn't clean up correctly and crashes with SIGSEGV / SIGABRT at the end. Probably an issue with wrtc package.
|
|
@@ -119,7 +106,6 @@ describe('WebRTCTransportProxy', function () {
|
|
|
119
106
|
const topic = PublicKey.random();
|
|
120
107
|
const peer1Id = PublicKey.random();
|
|
121
108
|
const peer2Id = PublicKey.random();
|
|
122
|
-
const sessionId = PublicKey.random();
|
|
123
109
|
|
|
124
110
|
const plugin1 = new TestProtocolPlugin(peer1Id.asBuffer());
|
|
125
111
|
const protocolProvider1 = testProtocolProvider(topic.asBuffer(), peer1Id.asBuffer(), plugin1);
|
|
@@ -129,13 +115,9 @@ describe('WebRTCTransportProxy', function () {
|
|
|
129
115
|
channel: discoveryKey(topic),
|
|
130
116
|
initiator: true
|
|
131
117
|
}).stream,
|
|
132
|
-
|
|
133
|
-
remoteId: peer2Id,
|
|
134
|
-
sessionId,
|
|
135
|
-
topic,
|
|
136
|
-
sendSignal: async (msg) => {
|
|
118
|
+
sendSignal: async (signal) => {
|
|
137
119
|
await sleep(10);
|
|
138
|
-
await connection2.signal(
|
|
120
|
+
await connection2.signal(signal);
|
|
139
121
|
}
|
|
140
122
|
});
|
|
141
123
|
afterTest(() => connection1.errors.assertNoUnhandledErrors());
|
|
@@ -148,13 +130,9 @@ describe('WebRTCTransportProxy', function () {
|
|
|
148
130
|
channel: discoveryKey(topic),
|
|
149
131
|
initiator: false
|
|
150
132
|
}).stream,
|
|
151
|
-
|
|
152
|
-
remoteId: peer1Id,
|
|
153
|
-
sessionId,
|
|
154
|
-
topic,
|
|
155
|
-
sendSignal: async (msg) => {
|
|
133
|
+
sendSignal: async (signal) => {
|
|
156
134
|
await sleep(10);
|
|
157
|
-
await connection1.signal(
|
|
135
|
+
await connection1.signal(signal);
|
|
158
136
|
}
|
|
159
137
|
});
|
|
160
138
|
afterTest(() => connection2.errors.assertNoUnhandledErrors());
|
|
@@ -169,7 +147,6 @@ describe('WebRTCTransportProxy', function () {
|
|
|
169
147
|
plugin2.on('connect', async (protocol) => {
|
|
170
148
|
await plugin2.send(peer1Id.asBuffer(), '{"message": "Hello"}');
|
|
171
149
|
});
|
|
172
|
-
|
|
173
150
|
await waitForExpect(() => {
|
|
174
151
|
expect(received.length).toBe(2);
|
|
175
152
|
expect(received[0]).toBeInstanceOf(Protocol);
|
|
@@ -188,7 +165,6 @@ describe('WebRTCTransportProxy', function () {
|
|
|
188
165
|
|
|
189
166
|
const webRTCTransportService: BridgeService = new WebRTCTransportService();
|
|
190
167
|
service = createProtoRpcPeer({
|
|
191
|
-
requested: {},
|
|
192
168
|
exposed: {
|
|
193
169
|
BridgeService: schema.getService('dxos.mesh.bridge.BridgeService')
|
|
194
170
|
},
|
|
@@ -205,8 +181,6 @@ describe('WebRTCTransportProxy', function () {
|
|
|
205
181
|
requested: {
|
|
206
182
|
BridgeService: schema.getService('dxos.mesh.bridge.BridgeService')
|
|
207
183
|
},
|
|
208
|
-
exposed: {},
|
|
209
|
-
handlers: {},
|
|
210
184
|
port: port2,
|
|
211
185
|
noHandshake: true,
|
|
212
186
|
encodingOptions: {
|
|
@@ -225,7 +199,6 @@ describe('WebRTCTransportProxy', function () {
|
|
|
225
199
|
const topic = PublicKey.random();
|
|
226
200
|
const peer1Id = PublicKey.random();
|
|
227
201
|
const peer2Id = PublicKey.random();
|
|
228
|
-
const sessionId = PublicKey.random();
|
|
229
202
|
|
|
230
203
|
const plugin1 = new TestProtocolPlugin(peer1Id.asBuffer());
|
|
231
204
|
const protocolProvider1 = testProtocolProvider(topic.asBuffer(), peer1Id.asBuffer(), plugin1);
|
|
@@ -235,13 +208,9 @@ describe('WebRTCTransportProxy', function () {
|
|
|
235
208
|
channel: discoveryKey(topic),
|
|
236
209
|
initiator: true
|
|
237
210
|
}).stream,
|
|
238
|
-
|
|
239
|
-
remoteId: peer2Id,
|
|
240
|
-
sessionId,
|
|
241
|
-
topic,
|
|
242
|
-
sendSignal: async (msg) => {
|
|
211
|
+
sendSignal: async (signal) => {
|
|
243
212
|
await sleep(10);
|
|
244
|
-
await proxy2.signal(
|
|
213
|
+
await proxy2.signal(signal);
|
|
245
214
|
},
|
|
246
215
|
bridgeService: rpcClient.rpc.BridgeService
|
|
247
216
|
});
|
|
@@ -255,13 +224,9 @@ describe('WebRTCTransportProxy', function () {
|
|
|
255
224
|
channel: discoveryKey(topic),
|
|
256
225
|
initiator: false
|
|
257
226
|
}).stream,
|
|
258
|
-
|
|
259
|
-
remoteId: peer1Id,
|
|
260
|
-
sessionId,
|
|
261
|
-
topic,
|
|
262
|
-
sendSignal: async (msg) => {
|
|
227
|
+
sendSignal: async (signal) => {
|
|
263
228
|
await sleep(10);
|
|
264
|
-
await proxy1.signal(
|
|
229
|
+
await proxy1.signal(signal);
|
|
265
230
|
},
|
|
266
231
|
bridgeService: rpcClient.rpc.BridgeService
|
|
267
232
|
});
|
|
@@ -12,24 +12,20 @@ import { log } from '@dxos/log';
|
|
|
12
12
|
import { ConnectionState, BridgeEvent, BridgeService } from '@dxos/protocols/proto/dxos/mesh/bridge';
|
|
13
13
|
import { Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';
|
|
14
14
|
|
|
15
|
-
import { SignalMessage } from '../signal';
|
|
16
15
|
import { Transport, TransportFactory, TransportOptions } from './transport';
|
|
17
16
|
|
|
18
|
-
export
|
|
17
|
+
export type WebRTCTransportProxyParams = {
|
|
19
18
|
initiator: boolean;
|
|
20
19
|
stream: NodeJS.ReadWriteStream;
|
|
21
|
-
ownId: PublicKey;
|
|
22
|
-
remoteId: PublicKey;
|
|
23
|
-
sessionId: PublicKey;
|
|
24
|
-
topic: PublicKey;
|
|
25
|
-
sendSignal: (msg: SignalMessage) => void;
|
|
26
20
|
bridgeService: BridgeService;
|
|
27
|
-
|
|
21
|
+
sendSignal: (signal: Signal) => Promise<void>;
|
|
22
|
+
};
|
|
28
23
|
|
|
29
24
|
export class WebRTCTransportProxy implements Transport {
|
|
30
25
|
readonly closed = new Event();
|
|
31
26
|
private _closed = false;
|
|
32
27
|
readonly connected = new Event();
|
|
28
|
+
|
|
33
29
|
readonly errors = new ErrorStream();
|
|
34
30
|
|
|
35
31
|
private _serviceStream!: Stream<BridgeEvent>;
|
|
@@ -43,16 +39,16 @@ export class WebRTCTransportProxy implements Transport {
|
|
|
43
39
|
proxyId: this._proxyId,
|
|
44
40
|
initiator: this._params.initiator
|
|
45
41
|
});
|
|
46
|
-
|
|
47
42
|
this._serviceStream.waitUntilReady().then(
|
|
48
43
|
() => {
|
|
49
|
-
this._serviceStream.subscribe(async (
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
44
|
+
this._serviceStream.subscribe(async (event: BridgeEvent) => {
|
|
45
|
+
log('WebRTCTransportProxy: event', event);
|
|
46
|
+
if (event.connection) {
|
|
47
|
+
await this._handleConnection(event.connection);
|
|
48
|
+
} else if (event.data) {
|
|
49
|
+
this._handleData(event.data);
|
|
50
|
+
} else if (event.signal) {
|
|
51
|
+
await this._handleSignal(event.signal);
|
|
56
52
|
}
|
|
57
53
|
});
|
|
58
54
|
|
|
@@ -94,13 +90,7 @@ export class WebRTCTransportProxy implements Transport {
|
|
|
94
90
|
}
|
|
95
91
|
|
|
96
92
|
private async _handleSignal(signalEvent: BridgeEvent.SignalEvent) {
|
|
97
|
-
await this._params.sendSignal(
|
|
98
|
-
author: this._params.ownId,
|
|
99
|
-
recipient: this._params.remoteId,
|
|
100
|
-
topic: this._params.topic,
|
|
101
|
-
sessionId: this._params.sessionId,
|
|
102
|
-
data: { signal: signalEvent.payload }
|
|
103
|
-
});
|
|
93
|
+
await this._params.sendSignal(signalEvent.payload);
|
|
104
94
|
}
|
|
105
95
|
|
|
106
96
|
async signal(signal: Signal): Promise<void> {
|