@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
|
@@ -3,10 +3,9 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import assert from 'assert';
|
|
6
|
-
import
|
|
6
|
+
import { Duplex } from 'stream';
|
|
7
7
|
|
|
8
8
|
import { Stream } from '@dxos/codec-protobuf';
|
|
9
|
-
import { raise } from '@dxos/debug';
|
|
10
9
|
import { PublicKey } from '@dxos/keys';
|
|
11
10
|
import { log } from '@dxos/log';
|
|
12
11
|
import {
|
|
@@ -20,10 +19,12 @@ import {
|
|
|
20
19
|
} from '@dxos/protocols/proto/dxos/mesh/bridge';
|
|
21
20
|
import { ComplexMap } from '@dxos/util';
|
|
22
21
|
|
|
23
|
-
import {
|
|
22
|
+
import { WebRTCTransport } from './webrtc-transport';
|
|
24
23
|
|
|
25
24
|
export class WebRTCTransportService implements BridgeService {
|
|
26
|
-
|
|
25
|
+
private readonly transports = new ComplexMap<PublicKey, { transport: WebRTCTransport; stream: Duplex }>(
|
|
26
|
+
PublicKey.hash
|
|
27
|
+
);
|
|
27
28
|
|
|
28
29
|
// prettier-ignore
|
|
29
30
|
constructor(
|
|
@@ -31,14 +32,23 @@ export class WebRTCTransportService implements BridgeService {
|
|
|
31
32
|
) {}
|
|
32
33
|
|
|
33
34
|
open(request: ConnectionRequest): Stream<BridgeEvent> {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
const rpcStream: Stream<BridgeEvent> = new Stream(({ ready, next, close }) => {
|
|
36
|
+
const duplex: Duplex = new Duplex({
|
|
37
|
+
read: () => {},
|
|
38
|
+
write: function (chunk, _, callback) {
|
|
39
|
+
next({ data: { payload: chunk } });
|
|
40
|
+
callback();
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const transport = new WebRTCTransport({
|
|
39
45
|
initiator: request.initiator,
|
|
40
|
-
|
|
41
|
-
|
|
46
|
+
stream: duplex,
|
|
47
|
+
sendSignal: async (signal) => {
|
|
48
|
+
next({
|
|
49
|
+
signal: { payload: signal }
|
|
50
|
+
});
|
|
51
|
+
}
|
|
42
52
|
});
|
|
43
53
|
|
|
44
54
|
next({
|
|
@@ -47,23 +57,7 @@ export class WebRTCTransportService implements BridgeService {
|
|
|
47
57
|
}
|
|
48
58
|
});
|
|
49
59
|
|
|
50
|
-
|
|
51
|
-
next({
|
|
52
|
-
data: {
|
|
53
|
-
payload
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
peer.on('signal', async (data) => {
|
|
59
|
-
next({
|
|
60
|
-
signal: {
|
|
61
|
-
payload: { json: JSON.stringify(data) }
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
peer.on('connect', () => {
|
|
60
|
+
transport.connected.on(() => {
|
|
67
61
|
next({
|
|
68
62
|
connection: {
|
|
69
63
|
state: ConnectionState.CONNECTED
|
|
@@ -71,7 +65,7 @@ export class WebRTCTransportService implements BridgeService {
|
|
|
71
65
|
});
|
|
72
66
|
});
|
|
73
67
|
|
|
74
|
-
|
|
68
|
+
transport.errors.handle((err) => {
|
|
75
69
|
next({
|
|
76
70
|
connection: {
|
|
77
71
|
state: ConnectionState.CLOSED,
|
|
@@ -81,7 +75,7 @@ export class WebRTCTransportService implements BridgeService {
|
|
|
81
75
|
close(err);
|
|
82
76
|
});
|
|
83
77
|
|
|
84
|
-
|
|
78
|
+
transport.closed.on(() => {
|
|
85
79
|
next({
|
|
86
80
|
connection: {
|
|
87
81
|
state: ConnectionState.CLOSED
|
|
@@ -90,26 +84,27 @@ export class WebRTCTransportService implements BridgeService {
|
|
|
90
84
|
close();
|
|
91
85
|
});
|
|
92
86
|
|
|
93
|
-
this.peers.set(request.proxyId, peer);
|
|
94
|
-
|
|
95
87
|
ready();
|
|
88
|
+
this.transports.set(request.proxyId, { transport, stream: duplex });
|
|
96
89
|
});
|
|
90
|
+
|
|
91
|
+
return rpcStream;
|
|
97
92
|
}
|
|
98
93
|
|
|
99
94
|
async sendSignal({ proxyId, signal }: SignalRequest): Promise<void> {
|
|
100
|
-
assert(this.
|
|
101
|
-
|
|
102
|
-
this.peers.get(proxyId)!.signal(JSON.parse(signal.json));
|
|
95
|
+
assert(this.transports.has(proxyId));
|
|
96
|
+
await this.transports.get(proxyId)!.transport.signal(signal);
|
|
103
97
|
}
|
|
104
98
|
|
|
105
99
|
async sendData({ proxyId, payload }: DataRequest): Promise<void> {
|
|
106
|
-
assert(this.
|
|
107
|
-
this.
|
|
100
|
+
assert(this.transports.has(proxyId));
|
|
101
|
+
await this.transports.get(proxyId)!.stream.push(payload);
|
|
108
102
|
}
|
|
109
103
|
|
|
110
104
|
async close({ proxyId }: CloseRequest) {
|
|
111
|
-
this.
|
|
112
|
-
this.
|
|
105
|
+
await this.transports.get(proxyId)?.transport.close();
|
|
106
|
+
await this.transports.get(proxyId)?.stream.end();
|
|
107
|
+
this.transports.delete(proxyId);
|
|
113
108
|
log('Closed.');
|
|
114
109
|
}
|
|
115
110
|
}
|
|
@@ -18,15 +18,11 @@ import { WebRTCTransport } from './webrtc-transport';
|
|
|
18
18
|
describe('WebRTCTransport', function () {
|
|
19
19
|
// This doesn't clean up correctly and crashes with SIGSEGV / SIGABRT at the end. Probably an issue with wrtc package.
|
|
20
20
|
it('open and close', async function () {
|
|
21
|
-
const connection = new WebRTCTransport(
|
|
22
|
-
true,
|
|
23
|
-
new Duplex(),
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
PublicKey.random(),
|
|
27
|
-
PublicKey.random(),
|
|
28
|
-
async (msg) => {}
|
|
29
|
-
);
|
|
21
|
+
const connection = new WebRTCTransport({
|
|
22
|
+
initiator: true,
|
|
23
|
+
stream: new Duplex(),
|
|
24
|
+
sendSignal: async () => {}
|
|
25
|
+
});
|
|
30
26
|
|
|
31
27
|
let callsCounter = 0;
|
|
32
28
|
const closedCb = () => {
|
|
@@ -48,45 +44,36 @@ describe('WebRTCTransport', function () {
|
|
|
48
44
|
const topic = PublicKey.random();
|
|
49
45
|
const peer1Id = PublicKey.random();
|
|
50
46
|
const peer2Id = PublicKey.random();
|
|
51
|
-
const sessionId = PublicKey.random();
|
|
52
47
|
|
|
53
48
|
const plugin1 = new TestProtocolPlugin(peer1Id.asBuffer());
|
|
54
49
|
const protocolProvider1 = testProtocolProvider(topic.asBuffer(), peer1Id.asBuffer(), plugin1);
|
|
55
|
-
const connection1 = new WebRTCTransport(
|
|
56
|
-
true,
|
|
57
|
-
protocolProvider1({
|
|
50
|
+
const connection1 = new WebRTCTransport({
|
|
51
|
+
initiator: true,
|
|
52
|
+
stream: protocolProvider1({
|
|
58
53
|
channel: discoveryKey(topic),
|
|
59
54
|
initiator: true
|
|
60
55
|
}).stream,
|
|
61
|
-
|
|
62
|
-
peer2Id,
|
|
63
|
-
sessionId,
|
|
64
|
-
topic,
|
|
65
|
-
async (msg) => {
|
|
56
|
+
sendSignal: async (signal) => {
|
|
66
57
|
await sleep(10);
|
|
67
|
-
await connection2.signal(
|
|
58
|
+
await connection2.signal(signal);
|
|
68
59
|
}
|
|
69
|
-
);
|
|
60
|
+
});
|
|
70
61
|
afterTest(() => connection1.close());
|
|
71
62
|
afterTest(() => connection1.errors.assertNoUnhandledErrors());
|
|
72
63
|
|
|
73
64
|
const plugin2 = new TestProtocolPlugin(peer2Id.asBuffer());
|
|
74
65
|
const protocolProvider2 = testProtocolProvider(topic.asBuffer(), peer2Id.asBuffer(), plugin2);
|
|
75
|
-
const connection2 = new WebRTCTransport(
|
|
76
|
-
false,
|
|
77
|
-
protocolProvider2({
|
|
66
|
+
const connection2 = new WebRTCTransport({
|
|
67
|
+
initiator: false,
|
|
68
|
+
stream: protocolProvider2({
|
|
78
69
|
channel: discoveryKey(topic),
|
|
79
70
|
initiator: false
|
|
80
71
|
}).stream,
|
|
81
|
-
|
|
82
|
-
peer1Id,
|
|
83
|
-
sessionId,
|
|
84
|
-
topic,
|
|
85
|
-
async (msg) => {
|
|
72
|
+
sendSignal: async (signal) => {
|
|
86
73
|
await sleep(10);
|
|
87
|
-
await connection1.signal(
|
|
74
|
+
await connection1.signal(signal);
|
|
88
75
|
}
|
|
89
|
-
);
|
|
76
|
+
});
|
|
90
77
|
afterTest(() => connection2.close());
|
|
91
78
|
afterTest(() => connection2.errors.assertNoUnhandledErrors());
|
|
92
79
|
|
|
@@ -7,14 +7,19 @@ import SimplePeerConstructor, { Instance as SimplePeer } from 'simple-peer';
|
|
|
7
7
|
|
|
8
8
|
import { Event } from '@dxos/async';
|
|
9
9
|
import { ErrorStream, raise } from '@dxos/debug';
|
|
10
|
-
import { PublicKey } from '@dxos/keys';
|
|
11
10
|
import { log } from '@dxos/log';
|
|
12
11
|
import { Signal } from '@dxos/protocols/proto/dxos/mesh/swarm';
|
|
13
12
|
|
|
14
|
-
import { SignalMessage } from '../signal';
|
|
15
13
|
import { Transport, TransportFactory } from './transport';
|
|
16
14
|
import { wrtc } from './webrtc';
|
|
17
15
|
|
|
16
|
+
export type WebRTCTransportParams = {
|
|
17
|
+
initiator: boolean;
|
|
18
|
+
stream: NodeJS.ReadWriteStream;
|
|
19
|
+
webrtcConfig?: any;
|
|
20
|
+
sendSignal: (signal: Signal) => Promise<void>;
|
|
21
|
+
};
|
|
22
|
+
|
|
18
23
|
/**
|
|
19
24
|
* Implements Transport for WebRTC. Uses simple-peer under the hood.
|
|
20
25
|
*/
|
|
@@ -25,51 +30,27 @@ export class WebRTCTransport implements Transport {
|
|
|
25
30
|
readonly connected = new Event();
|
|
26
31
|
readonly errors = new ErrorStream();
|
|
27
32
|
|
|
28
|
-
constructor(
|
|
29
|
-
|
|
30
|
-
private readonly _stream: NodeJS.ReadWriteStream,
|
|
31
|
-
private readonly _ownId: PublicKey,
|
|
32
|
-
private readonly _remoteId: PublicKey,
|
|
33
|
-
private readonly _sessionId: PublicKey,
|
|
34
|
-
private readonly _topic: PublicKey,
|
|
35
|
-
private readonly _sendSignal: (msg: SignalMessage) => void,
|
|
36
|
-
private readonly _webrtcConfig?: any
|
|
37
|
-
) {
|
|
38
|
-
log('created connection', {
|
|
39
|
-
id: this._ownId,
|
|
40
|
-
topic: this._topic,
|
|
41
|
-
remoteId: this._remoteId,
|
|
42
|
-
initiator: this._initiator,
|
|
43
|
-
config: this._webrtcConfig
|
|
44
|
-
});
|
|
33
|
+
constructor(private readonly params: WebRTCTransportParams) {
|
|
34
|
+
log('created connection', params);
|
|
45
35
|
this._peer = new SimplePeerConstructor({
|
|
46
|
-
initiator: this.
|
|
36
|
+
initiator: this.params.initiator,
|
|
47
37
|
wrtc: SimplePeerConstructor.WEBRTC_SUPPORT ? undefined : wrtc ?? raise(new Error('wrtc not available')),
|
|
48
|
-
config: this.
|
|
38
|
+
config: this.params.webrtcConfig
|
|
49
39
|
});
|
|
50
40
|
|
|
51
41
|
this._peer.on('signal', async (data) => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
author: this._ownId,
|
|
55
|
-
recipient: this._remoteId,
|
|
56
|
-
sessionId: this._sessionId,
|
|
57
|
-
topic: this._topic,
|
|
58
|
-
data: { signal: { json: JSON.stringify(data) } }
|
|
59
|
-
});
|
|
60
|
-
} catch (err: any) {
|
|
61
|
-
this.errors.raise(err);
|
|
62
|
-
}
|
|
42
|
+
log('signal', data);
|
|
43
|
+
await this.params.sendSignal({ json: JSON.stringify(data) });
|
|
63
44
|
});
|
|
64
45
|
|
|
65
46
|
this._peer.on('connect', () => {
|
|
66
|
-
log('connected'
|
|
67
|
-
this.
|
|
47
|
+
log('connected');
|
|
48
|
+
this.params.stream.pipe(this._peer!).pipe(this.params.stream);
|
|
68
49
|
this.connected.emit();
|
|
69
50
|
});
|
|
70
51
|
|
|
71
52
|
this._peer.on('close', async () => {
|
|
72
|
-
log('closed'
|
|
53
|
+
log('closed');
|
|
73
54
|
await this._disconnectStreams();
|
|
74
55
|
this.closed.emit();
|
|
75
56
|
});
|
|
@@ -80,14 +61,6 @@ export class WebRTCTransport implements Transport {
|
|
|
80
61
|
});
|
|
81
62
|
}
|
|
82
63
|
|
|
83
|
-
get remoteId() {
|
|
84
|
-
return this._remoteId;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
get sessionId() {
|
|
88
|
-
return this._sessionId;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
64
|
get peer() {
|
|
92
65
|
return this._peer;
|
|
93
66
|
}
|
|
@@ -96,6 +69,7 @@ export class WebRTCTransport implements Transport {
|
|
|
96
69
|
log('closing...');
|
|
97
70
|
await this._disconnectStreams();
|
|
98
71
|
this._peer!.destroy();
|
|
72
|
+
this.closed.emit();
|
|
99
73
|
log('closed');
|
|
100
74
|
}
|
|
101
75
|
|
|
@@ -107,21 +81,15 @@ export class WebRTCTransport implements Transport {
|
|
|
107
81
|
|
|
108
82
|
private async _disconnectStreams() {
|
|
109
83
|
// TODO(rzadp): Find a way of unpiping this?
|
|
110
|
-
this.
|
|
84
|
+
this.params.stream.unpipe?.(this._peer)?.unpipe?.(this.params.stream);
|
|
111
85
|
}
|
|
112
86
|
}
|
|
113
87
|
|
|
114
88
|
// TODO(dmaretskyi): Convert to class.
|
|
115
89
|
export const createWebRTCTransportFactory = (webrtcConfig?: any): TransportFactory => ({
|
|
116
|
-
create: (
|
|
117
|
-
new WebRTCTransport(
|
|
118
|
-
|
|
119
|
-
opts.stream,
|
|
120
|
-
opts.ownId,
|
|
121
|
-
opts.remoteId,
|
|
122
|
-
opts.sessionId,
|
|
123
|
-
opts.topic,
|
|
124
|
-
opts.sendSignal,
|
|
90
|
+
create: (params) =>
|
|
91
|
+
new WebRTCTransport({
|
|
92
|
+
...params,
|
|
125
93
|
webrtcConfig
|
|
126
|
-
)
|
|
94
|
+
})
|
|
127
95
|
});
|