@dxos/signal 2.33.9-dev.2637427f → 2.33.9-dev.46220a19
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/.eslintrc.js +6 -0
- package/.rush/temp/package-deps_build_test.json +17 -0
- package/.rush/temp/shrinkwrap-deps.json +297 -0
- package/bin/signal-test-darwin-amd64 +0 -0
- package/bin/signal-test-darwin-arm64 +0 -0
- package/bin/signal-test-linux-amd64 +0 -0
- package/bin/signal-test-linux-arm64 +0 -0
- package/bin/signal.js +0 -0
- package/dist/src/index.d.ts +1 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -4
- package/dist/src/index.js.map +1 -1
- package/dist/src/test-broker.d.ts +19 -0
- package/dist/src/test-broker.d.ts.map +1 -0
- package/dist/src/test-broker.js +104 -0
- package/dist/src/test-broker.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +11 -57
- package/signal.build.log +13 -0
- package/src/index.ts +2 -4
- package/src/test-broker.ts +94 -0
- package/tsconfig.json +20 -0
- package/dist/package.json +0 -94
- package/dist/src/bin.d.ts +0 -3
- package/dist/src/bin.d.ts.map +0 -1
- package/dist/src/bin.js +0 -79
- package/dist/src/bin.js.map +0 -1
- package/dist/src/broker.d.ts +0 -30
- package/dist/src/broker.d.ts.map +0 -1
- package/dist/src/broker.js +0 -99
- package/dist/src/broker.js.map +0 -1
- package/dist/src/broker.test.d.ts +0 -2
- package/dist/src/broker.test.d.ts.map +0 -1
- package/dist/src/broker.test.js +0 -30
- package/dist/src/broker.test.js.map +0 -1
- package/dist/src/presence.test.d.ts +0 -2
- package/dist/src/presence.test.d.ts.map +0 -1
- package/dist/src/presence.test.js +0 -54
- package/dist/src/presence.test.js.map +0 -1
- package/dist/src/serializer.d.ts +0 -7
- package/dist/src/serializer.d.ts.map +0 -1
- package/dist/src/serializer.js +0 -21
- package/dist/src/serializer.js.map +0 -1
- package/dist/src/services/discovery.d.ts +0 -21
- package/dist/src/services/discovery.d.ts.map +0 -1
- package/dist/src/services/discovery.js +0 -93
- package/dist/src/services/discovery.js.map +0 -1
- package/dist/src/services/index.d.ts +0 -6
- package/dist/src/services/index.d.ts.map +0 -1
- package/dist/src/services/index.js +0 -25
- package/dist/src/services/index.js.map +0 -1
- package/dist/src/services/network.d.ts +0 -24
- package/dist/src/services/network.d.ts.map +0 -1
- package/dist/src/services/network.js +0 -105
- package/dist/src/services/network.js.map +0 -1
- package/dist/src/services/presence.d.ts +0 -17
- package/dist/src/services/presence.d.ts.map +0 -1
- package/dist/src/services/presence.js +0 -74
- package/dist/src/services/presence.js.map +0 -1
- package/dist/src/services/status.d.ts +0 -46
- package/dist/src/services/status.d.ts.map +0 -1
- package/dist/src/services/status.js +0 -248
- package/dist/src/services/status.js.map +0 -1
- package/dist/src/services/web.d.ts +0 -8
- package/dist/src/services/web.d.ts.map +0 -1
- package/dist/src/services/web.js +0 -28
- package/dist/src/services/web.js.map +0 -1
- package/dist/src/signal/index.d.ts +0 -3
- package/dist/src/signal/index.d.ts.map +0 -1
- package/dist/src/signal/index.js +0 -22
- package/dist/src/signal/index.js.map +0 -1
- package/dist/src/signal/peer-map.d.ts +0 -63
- package/dist/src/signal/peer-map.d.ts.map +0 -1
- package/dist/src/signal/peer-map.js +0 -135
- package/dist/src/signal/peer-map.js.map +0 -1
- package/dist/src/signal/peer-map.test.d.ts +0 -2
- package/dist/src/signal/peer-map.test.d.ts.map +0 -1
- package/dist/src/signal/peer-map.test.js +0 -44
- package/dist/src/signal/peer-map.test.js.map +0 -1
- package/dist/src/signal/signal-server.d.ts +0 -17
- package/dist/src/signal/signal-server.d.ts.map +0 -1
- package/dist/src/signal/signal-server.js +0 -92
- package/dist/src/signal/signal-server.js.map +0 -1
- package/dist/src/signal.test.d.ts +0 -2
- package/dist/src/signal.test.d.ts.map +0 -1
- package/dist/src/signal.test.js +0 -67
- package/dist/src/signal.test.js.map +0 -1
- package/dist/src/system-information.d.ts +0 -5
- package/dist/src/system-information.d.ts.map +0 -1
- package/dist/src/system-information.js +0 -96
- package/dist/src/system-information.js.map +0 -1
- package/dist/src/testing.d.ts +0 -9
- package/dist/src/testing.d.ts.map +0 -1
- package/dist/src/testing.js +0 -25
- package/dist/src/testing.js.map +0 -1
- package/dist/src/transporter/bootstrap-node.d.ts +0 -2
- package/dist/src/transporter/bootstrap-node.d.ts.map +0 -1
- package/dist/src/transporter/bootstrap-node.js +0 -95
- package/dist/src/transporter/bootstrap-node.js.map +0 -1
- package/dist/src/transporter/index.d.ts +0 -38
- package/dist/src/transporter/index.d.ts.map +0 -1
- package/dist/src/transporter/index.js +0 -151
- package/dist/src/transporter/index.js.map +0 -1
- package/dist/src/transporter/messenger.d.ts +0 -2
- package/dist/src/transporter/messenger.d.ts.map +0 -1
- package/dist/src/transporter/messenger.js +0 -193
- package/dist/src/transporter/messenger.js.map +0 -1
- package/src/bin.ts +0 -81
- package/src/broker.test.js +0 -35
- package/src/broker.ts +0 -134
- package/src/presence.test.js +0 -67
- package/src/serializer.js +0 -17
- package/src/services/discovery.js +0 -101
- package/src/services/index.ts +0 -9
- package/src/services/network.ts +0 -129
- package/src/services/presence.js +0 -77
- package/src/services/status.js +0 -259
- package/src/services/web.ts +0 -24
- package/src/shims.d.ts +0 -6
- package/src/signal/index.ts +0 -6
- package/src/signal/peer-map.test.js +0 -58
- package/src/signal/peer-map.ts +0 -174
- package/src/signal/signal-server.js +0 -106
- package/src/signal.test.js +0 -78
- package/src/system-information.ts +0 -110
- package/src/testing.ts +0 -27
- package/src/transporter/bootstrap-node.js +0 -112
- package/src/transporter/index.js +0 -179
- package/src/transporter/messenger.js +0 -223
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2021 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { PeerMap } from './peer-map';
|
|
6
|
-
|
|
7
|
-
const bf = str => Buffer.from(str);
|
|
8
|
-
|
|
9
|
-
test('basic operations', () => {
|
|
10
|
-
const map = new PeerMap(bf('owner1'));
|
|
11
|
-
|
|
12
|
-
const onAdd = jest.fn();
|
|
13
|
-
const onDel = jest.fn();
|
|
14
|
-
|
|
15
|
-
map.on('peer-added', onAdd);
|
|
16
|
-
map.on('peer-deleted', onDel);
|
|
17
|
-
|
|
18
|
-
expect(map.peers.length).toBe(0);
|
|
19
|
-
|
|
20
|
-
map.add({ id: bf('peer1'), topic: bf('topic1'), rpc: {} });
|
|
21
|
-
map.add({ id: bf('peer2'), topic: bf('topic1'), rpc: {} });
|
|
22
|
-
map.add({ id: bf('peer3'), topic: bf('topic2'), rpc: {} });
|
|
23
|
-
map.add({ id: bf('peer4'), topic: bf('topic3'), rpc: {} });
|
|
24
|
-
map.add({ id: bf('peer5'), topic: bf('topic3'), rpc: {} });
|
|
25
|
-
|
|
26
|
-
expect(map.peers.length).toBe(5);
|
|
27
|
-
expect(map.topics.length).toBe(3);
|
|
28
|
-
|
|
29
|
-
expect(map.delete(bf('topic3'), bf('peer4'))).toBe(true);
|
|
30
|
-
expect(map.delete(bf('topic3'), bf('peer5'))).toBe(true);
|
|
31
|
-
|
|
32
|
-
// Delete false.
|
|
33
|
-
expect(map.delete(bf('topicx'), bf('peer6'))).toBe(false);
|
|
34
|
-
expect(map.delete(bf('topic2'), bf('peerx'))).toBe(false);
|
|
35
|
-
|
|
36
|
-
expect(map.peers.length).toBe(3);
|
|
37
|
-
expect(map.topics.length).toBe(2);
|
|
38
|
-
|
|
39
|
-
expect(onAdd).toHaveBeenCalledTimes(5);
|
|
40
|
-
expect(onDel).toHaveBeenCalledTimes(2);
|
|
41
|
-
|
|
42
|
-
expect(map.getPeersByTopic(bf('topic2')).length).toBe(1);
|
|
43
|
-
|
|
44
|
-
map.updatePeersByOwner(bf('owner2'), [
|
|
45
|
-
{ id: bf('peer6'), topic: bf('topic1') },
|
|
46
|
-
{ id: bf('peer7'), topic: bf('topic2') }
|
|
47
|
-
]);
|
|
48
|
-
|
|
49
|
-
expect(map.peers.length).toBe(5);
|
|
50
|
-
expect(map.topics.length).toBe(2);
|
|
51
|
-
|
|
52
|
-
map.updatePeersByOwner(bf('owner2'), [
|
|
53
|
-
{ id: bf('peer6'), topic: bf('topic1') }
|
|
54
|
-
]);
|
|
55
|
-
|
|
56
|
-
expect(map.peers.length).toBe(4);
|
|
57
|
-
expect(map.topics.length).toBe(2);
|
|
58
|
-
});
|
package/src/signal/peer-map.ts
DELETED
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2021 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import { EventEmitter } from 'events';
|
|
6
|
-
import assert from 'node:assert';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* @typedef Peer
|
|
10
|
-
* @prop {Buffer} id
|
|
11
|
-
* @prop {Buffer} topic
|
|
12
|
-
* @prop {Buffer} owner
|
|
13
|
-
* @prop {NanomessageRPC} [rpc]
|
|
14
|
-
*/
|
|
15
|
-
interface Peer {
|
|
16
|
-
id: Buffer,
|
|
17
|
-
topic: Buffer,
|
|
18
|
-
owner: Buffer,
|
|
19
|
-
rpc: any[]
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export class PeerMap extends EventEmitter {
|
|
23
|
-
private readonly _owner: Buffer;
|
|
24
|
-
private readonly _peersByTopic: Map<string, Map<string, Peer>>;
|
|
25
|
-
|
|
26
|
-
constructor (owner: Buffer) {
|
|
27
|
-
super();
|
|
28
|
-
|
|
29
|
-
this._owner = owner;
|
|
30
|
-
this._peersByTopic = new Map();
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
get peers () : Peer[] {
|
|
34
|
-
const result = [];
|
|
35
|
-
for (const peers of this._peersByTopic.values()) {
|
|
36
|
-
for (const peer of peers.values()) {
|
|
37
|
-
result.push(peer);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
return result;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
get topics (): Array<Buffer> {
|
|
44
|
-
return Array.from(this._peersByTopic.keys()).map(topic => Buffer.from(topic, 'hex'));
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Add a new peer
|
|
49
|
-
*/
|
|
50
|
-
add (opts: {
|
|
51
|
-
id?: Buffer,
|
|
52
|
-
topic?: Buffer,
|
|
53
|
-
owner?: Buffer,
|
|
54
|
-
rpc?: any,
|
|
55
|
-
} = {}): Peer {
|
|
56
|
-
const { id, topic, owner = this._owner, rpc } = opts;
|
|
57
|
-
|
|
58
|
-
assert(id && Buffer.isBuffer(id));
|
|
59
|
-
assert(topic && Buffer.isBuffer(topic));
|
|
60
|
-
|
|
61
|
-
const idStr = id.toString('hex');
|
|
62
|
-
const topicStr = topic.toString('hex');
|
|
63
|
-
|
|
64
|
-
let peers;
|
|
65
|
-
if (this._peersByTopic.has(topicStr)) {
|
|
66
|
-
peers = this._peersByTopic.get(topicStr);
|
|
67
|
-
} else {
|
|
68
|
-
peers = new Map();
|
|
69
|
-
this._peersByTopic.set(topicStr, peers);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const peer = {
|
|
73
|
-
id,
|
|
74
|
-
topic,
|
|
75
|
-
owner,
|
|
76
|
-
rpc
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
peers?.set(idStr, peer);
|
|
80
|
-
if (this._owner.equals(owner)) {
|
|
81
|
-
this.emit('peer-added', peer);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return peer;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Delete a peer by topic and id
|
|
89
|
-
*/
|
|
90
|
-
delete (topic: Buffer, id: Buffer): boolean {
|
|
91
|
-
const peer = this._delete(topic, id);
|
|
92
|
-
|
|
93
|
-
if (peer) {
|
|
94
|
-
if (this._owner.equals(peer.owner)) {
|
|
95
|
-
this.emit('peer-deleted', peer);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return true;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
return false;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
getPeersByTopic (topic: Buffer): Peer[] {
|
|
105
|
-
const topicStr = topic.toString('hex');
|
|
106
|
-
if (!this._peersByTopic.has(topicStr)) {
|
|
107
|
-
return [];
|
|
108
|
-
}
|
|
109
|
-
const peers = this._peersByTopic.get(topicStr);
|
|
110
|
-
return Array.from(peers?.values() ?? []);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
deletePeersByOwner (owner: Buffer) {
|
|
114
|
-
for (const peer of this.peers) {
|
|
115
|
-
if (!peer.owner.equals(owner)) {
|
|
116
|
-
continue;
|
|
117
|
-
}
|
|
118
|
-
this._delete(peer.topic, peer.id);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* @param {NanomessageRPC} rpc
|
|
124
|
-
*/
|
|
125
|
-
deletePeersByRPC (rpc: any) {
|
|
126
|
-
for (const peer of this.peers) {
|
|
127
|
-
if (peer.rpc !== rpc) {
|
|
128
|
-
continue;
|
|
129
|
-
}
|
|
130
|
-
this._delete(peer.topic, peer.id);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
updatePeersByOwner (owner: Buffer, peers: Array<{ id: Buffer, topic: Buffer }>) {
|
|
135
|
-
this.deletePeersByOwner(owner);
|
|
136
|
-
peers.forEach(peer => this.add({
|
|
137
|
-
id: peer.id,
|
|
138
|
-
topic: peer.topic,
|
|
139
|
-
owner
|
|
140
|
-
}));
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
encode (peer: Peer) {
|
|
144
|
-
return { id: peer.id.toString('hex'), topic: peer.topic.toString('hex'), owner: peer.owner.toString('hex') };
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
decode (peer: {id: string, topic: string, owner: string}) {
|
|
148
|
-
return { id: Buffer.from(peer.id, 'hex'), topic: Buffer.from(peer.topic, 'hex'), owner: Buffer.from(peer.owner, 'hex') };
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
_delete (topic: Buffer, id: Buffer): Peer | null {
|
|
152
|
-
const topicStr = topic.toString('hex');
|
|
153
|
-
const idStr = id.toString('hex');
|
|
154
|
-
|
|
155
|
-
if (this._peersByTopic.has(topicStr)) {
|
|
156
|
-
const peers = this._peersByTopic.get(topicStr);
|
|
157
|
-
if (!peers) {
|
|
158
|
-
return null;
|
|
159
|
-
}
|
|
160
|
-
const peer = peers.get(idStr);
|
|
161
|
-
if (peer) {
|
|
162
|
-
peers.delete(idStr);
|
|
163
|
-
|
|
164
|
-
if (peers.size === 0) {
|
|
165
|
-
this._peersByTopic.delete(topicStr);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
return peer;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
return null;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2021 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import Server from 'simple-websocket/server';
|
|
6
|
-
|
|
7
|
-
const { SocketSignalServer, errors: { ERR_PEER_NOT_FOUND } } = require('socket-signal'); // eslint-disable-line @typescript-eslint/no-var-requires
|
|
8
|
-
|
|
9
|
-
export class SignalServer extends SocketSignalServer {
|
|
10
|
-
constructor (server, broker, opts = {}) {
|
|
11
|
-
const { path, ...signalOpts } = opts;
|
|
12
|
-
|
|
13
|
-
super(signalOpts);
|
|
14
|
-
|
|
15
|
-
const { keyPair, peerMap } = broker.shared;
|
|
16
|
-
|
|
17
|
-
this._broker = broker;
|
|
18
|
-
this._keyPair = keyPair;
|
|
19
|
-
this._peerMap = peerMap;
|
|
20
|
-
|
|
21
|
-
this._server = new Server({ server, path });
|
|
22
|
-
this._server.setMaxListeners(Infinity);
|
|
23
|
-
|
|
24
|
-
this.on('error', err => this._broker.logger.warn('signal-server', err));
|
|
25
|
-
this.on('rpc-error', err => this._broker.logger.warn('rpc-signal-server', err));
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
_onSocket (socket) {
|
|
29
|
-
this.addSocket(socket).catch(err => process.nextTick(() => this.emit('error', err)));
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
async _open () {
|
|
33
|
-
this._server.on('connection', this._onSocket.bind(this));
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
async _close () {
|
|
37
|
-
this._server.removeListener('connection', this._onSocket.bind(this));
|
|
38
|
-
await super._close();
|
|
39
|
-
return new Promise(resolve => this._server.close(() => resolve()));
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
async _onDisconnect (rpc) {
|
|
43
|
-
const peer = this._peerMap.peers.find(p => p.rpc === rpc);
|
|
44
|
-
if (peer) {
|
|
45
|
-
this._peerMap.peers
|
|
46
|
-
.filter(p => p.rpc === rpc)
|
|
47
|
-
.forEach(p => this._peerMap.delete(p.topic, p.id));
|
|
48
|
-
|
|
49
|
-
this._broker.logger.info('peer-disconnected', { id: peer.id.toString('hex') });
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
async _onJoin (rpc, data) {
|
|
54
|
-
this._peerMap.add({
|
|
55
|
-
id: data.id,
|
|
56
|
-
topic: data.topic,
|
|
57
|
-
owner: this._keyPair.publicKey,
|
|
58
|
-
rpc
|
|
59
|
-
});
|
|
60
|
-
this._broker.logger.info('peer-join', { topic: data.topic.toString('hex'), id: data.id.toString('hex') });
|
|
61
|
-
return this._peerMap.getPeersByTopic(data.topic).map(p => p.id);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
async _onLeave (rpc, data) {
|
|
65
|
-
this._broker.logger.info('peer-leave', { topic: data.topic.toString('hex'), id: data.id.toString('hex') });
|
|
66
|
-
this._peerMap.delete(data.topic, data.id);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
async _onOffer (rpc, data) {
|
|
70
|
-
const remotePeer = this._peerMap.peers.find(p => p.topic.equals(data.topic) && p.id.equals(data.remoteId));
|
|
71
|
-
if (!remotePeer) {
|
|
72
|
-
throw new ERR_PEER_NOT_FOUND(data.remoteId.toString('hex'));
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (remotePeer.owner.equals(this._keyPair.publicKey)) {
|
|
76
|
-
const rpc = remotePeer.rpc;
|
|
77
|
-
if (!rpc) {
|
|
78
|
-
throw new Error('rpc not found');
|
|
79
|
-
}
|
|
80
|
-
return rpc.call('offer', data);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return this._broker.call('discovery.offer', data, { nodeID: remotePeer.owner.toString('hex'), retries: 0 });
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
async _onSignal (rpc, data) {
|
|
87
|
-
const remotePeer = this._peerMap.peers.find(p => p.topic.equals(data.topic) && p.id.equals(data.remoteId));
|
|
88
|
-
if (!remotePeer) {
|
|
89
|
-
throw new ERR_PEER_NOT_FOUND(data.remoteId.toString('hex'));
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (remotePeer.owner.equals(this._keyPair.publicKey)) {
|
|
93
|
-
const rpc = remotePeer.rpc;
|
|
94
|
-
if (!rpc) {
|
|
95
|
-
throw new Error('rpc not found');
|
|
96
|
-
}
|
|
97
|
-
return rpc.emit('signal', data);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return this._broker.call('discovery.signal', data, { nodeID: remotePeer.owner.toString('hex'), retries: 0 });
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
async _onLookup (rpc, data) {
|
|
104
|
-
return this._peerMap.getPeersByTopic(data.topic).map(p => p.id);
|
|
105
|
-
}
|
|
106
|
-
}
|
package/src/signal.test.js
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2021 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import swarm from '@geut/discovery-swarm-webrtc';
|
|
6
|
-
import wrtc from '@koush/wrtc';
|
|
7
|
-
import crypto from 'crypto';
|
|
8
|
-
import debug from 'debug';
|
|
9
|
-
import pEvent from 'p-event';
|
|
10
|
-
|
|
11
|
-
import { createBroker } from './broker';
|
|
12
|
-
|
|
13
|
-
const log = debug('dxos:test:signal');
|
|
14
|
-
|
|
15
|
-
jest.setTimeout(100 * 1000);
|
|
16
|
-
|
|
17
|
-
const checkDiscoveryUpdate = (brokers, check) => Promise.all(brokers.map((broker) => pEvent(broker.localBus, '$broker.discovery-update', () => check(broker))));
|
|
18
|
-
|
|
19
|
-
// TODO(telackey): This test does not work for me.
|
|
20
|
-
test.skip('join/leave/connection webrtc peer', async () => {
|
|
21
|
-
const topic = crypto.randomBytes(32);
|
|
22
|
-
|
|
23
|
-
const brokers = [...Array(10).keys()].map(i => createBroker(topic, { port: 5000 + i, logger: false, hyperswarm: { bootstrap: false } }));
|
|
24
|
-
|
|
25
|
-
log('> starting brokers');
|
|
26
|
-
await Promise.all(brokers.map(b => b.start()));
|
|
27
|
-
|
|
28
|
-
const clients = [...Array(3).keys()].map(i => swarm({
|
|
29
|
-
bootstrap: [`ws://127.0.0.1:${5000 + i}`],
|
|
30
|
-
simplePeer: {
|
|
31
|
-
wrtc
|
|
32
|
-
}
|
|
33
|
-
}));
|
|
34
|
-
|
|
35
|
-
const peerIds = clients.map(c => c.id);
|
|
36
|
-
const waitForJoin = checkDiscoveryUpdate(brokers, broker => {
|
|
37
|
-
const { peerMap } = broker.shared;
|
|
38
|
-
|
|
39
|
-
return peerIds.reduce((prev, peerId) => prev && peerMap.peers.find(p => p.topic.equals(topic) && p.id.equals(peerId)), true);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
const waitForPeerConnections = new Promise(resolve => {
|
|
43
|
-
let connections = 0;
|
|
44
|
-
const done = (conn, { initiator }) => {
|
|
45
|
-
if (initiator) {
|
|
46
|
-
connections++;
|
|
47
|
-
}
|
|
48
|
-
if (connections >= 2) {
|
|
49
|
-
clients.forEach(client => client.off('connection', done));
|
|
50
|
-
resolve();
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
clients.forEach(client => client.on('connection', done));
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
log('> waiting for joining');
|
|
57
|
-
clients.forEach(client => client.join(topic));
|
|
58
|
-
await waitForJoin;
|
|
59
|
-
|
|
60
|
-
log('> waiting for webrtc connections');
|
|
61
|
-
await waitForPeerConnections;
|
|
62
|
-
|
|
63
|
-
log('> waiting for leaving');
|
|
64
|
-
const waitForLeave = checkDiscoveryUpdate(brokers, broker => {
|
|
65
|
-
const { peerMap } = broker.shared;
|
|
66
|
-
return peerMap.getPeersByTopic(topic).length === 0;
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
clients.forEach(client => client.leave(topic));
|
|
70
|
-
await waitForLeave;
|
|
71
|
-
log('> all left');
|
|
72
|
-
|
|
73
|
-
log('> stopping signals');
|
|
74
|
-
await Promise.all(clients.map(client => client.signal.close()));
|
|
75
|
-
log('> stopping brokers');
|
|
76
|
-
await Promise.all(brokers.map(b => b.stop()));
|
|
77
|
-
log('> stopped');
|
|
78
|
-
});
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copy from https://github.com/dxos/console/tree/master/packages/console-server
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
//
|
|
6
|
-
// Copyright 2021 DXOS.org
|
|
7
|
-
//
|
|
8
|
-
|
|
9
|
-
import { spawnSync } from 'child_process';
|
|
10
|
-
import fs from 'fs';
|
|
11
|
-
import pick from 'lodash.pick';
|
|
12
|
-
import moment from 'moment';
|
|
13
|
-
import os from 'os';
|
|
14
|
-
import si from 'systeminformation';
|
|
15
|
-
|
|
16
|
-
const num = new Intl.NumberFormat('en', { maximumSignificantDigits: 3 });
|
|
17
|
-
|
|
18
|
-
const size = (n: number, unit: 'K' | 'M' | 'G' | 'T') => {
|
|
19
|
-
const units = {
|
|
20
|
-
K: 3,
|
|
21
|
-
M: 6,
|
|
22
|
-
G: 9,
|
|
23
|
-
T: 12
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
const power = units[unit] || 0;
|
|
27
|
-
|
|
28
|
-
return num.format(Math.round(n / (10 ** power))) + (unit ? ` ${unit}` : '');
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const getVersionInfo = () => {
|
|
32
|
-
// TODO(telackey): Get from config (or figure out a better way to do this).
|
|
33
|
-
const versionFile = '/opt/kube/VERSION';
|
|
34
|
-
if (fs.existsSync(versionFile)) {
|
|
35
|
-
return fs.readFileSync(versionFile, { encoding: 'utf8' }).replace(/^\s+|\s+$/g, '');
|
|
36
|
-
}
|
|
37
|
-
return undefined;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Get system inforamtion.
|
|
42
|
-
* https://www.npmjs.com/package/systeminformation
|
|
43
|
-
*/
|
|
44
|
-
const getSystemInfo = async () => {
|
|
45
|
-
const ifaces = os.networkInterfaces();
|
|
46
|
-
const addresses = Object.entries(ifaces).reduce((result, [, values]) => {
|
|
47
|
-
(values ?? []).forEach(({ family, address }) => {
|
|
48
|
-
address = address.toLowerCase();
|
|
49
|
-
// TODO(telackey): Include link-local IPv6?
|
|
50
|
-
if (!address.startsWith('127.') && !address.startsWith('fe80::') && !address.startsWith('::1')) {
|
|
51
|
-
result.push(address);
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
return result;
|
|
55
|
-
}, [] as string[]);
|
|
56
|
-
|
|
57
|
-
const cpu = await si.cpu();
|
|
58
|
-
const memory = await si.mem();
|
|
59
|
-
const device = await si.system();
|
|
60
|
-
const hostname = os.hostname();
|
|
61
|
-
|
|
62
|
-
return {
|
|
63
|
-
cpu: pick(cpu, 'brand', 'cores', 'manufacturer', 'vendor', 'speed'),
|
|
64
|
-
|
|
65
|
-
memory: {
|
|
66
|
-
total: size(memory.total, 'M'),
|
|
67
|
-
free: size(memory.free, 'M'),
|
|
68
|
-
used: size(memory.used, 'M'),
|
|
69
|
-
swaptotal: size(memory.swaptotal, 'M')
|
|
70
|
-
},
|
|
71
|
-
|
|
72
|
-
device: pick(device, 'model', 'serial', 'version'),
|
|
73
|
-
|
|
74
|
-
network: {
|
|
75
|
-
hostname,
|
|
76
|
-
addresses
|
|
77
|
-
},
|
|
78
|
-
|
|
79
|
-
os: {
|
|
80
|
-
arch: os.arch(),
|
|
81
|
-
platform: os.platform(),
|
|
82
|
-
version: os.version ? os.version() : undefined // Node > 13.
|
|
83
|
-
},
|
|
84
|
-
|
|
85
|
-
time: {
|
|
86
|
-
now: moment(),
|
|
87
|
-
up: moment().subtract(os.uptime(), 'seconds')
|
|
88
|
-
},
|
|
89
|
-
|
|
90
|
-
nodejs: {
|
|
91
|
-
version: process.version
|
|
92
|
-
},
|
|
93
|
-
|
|
94
|
-
version: getVersionInfo()
|
|
95
|
-
};
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Get system inforamtion.
|
|
100
|
-
* https://www.npmjs.com/package/systeminformation
|
|
101
|
-
*/
|
|
102
|
-
const getServiceInfo = async () => {
|
|
103
|
-
const command = 'dx';
|
|
104
|
-
const args = ['service', '--json'];
|
|
105
|
-
|
|
106
|
-
const child = spawnSync(command, args, { encoding: 'utf8' });
|
|
107
|
-
return JSON.parse(child.stdout);
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
module.exports = { getServiceInfo, getSystemInfo };
|
package/src/testing.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2021 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import Moleculer from 'moleculer';
|
|
6
|
-
|
|
7
|
-
import { PublicKey } from '@dxos/protocols';
|
|
8
|
-
|
|
9
|
-
import { createBroker } from './broker';
|
|
10
|
-
|
|
11
|
-
export type TestBroker = Moleculer.ServiceBroker;
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Creates a test instance of the signal server with swarming disabled and starts it.
|
|
15
|
-
*
|
|
16
|
-
* @param port Port to start the signal server on, random by default.
|
|
17
|
-
*/
|
|
18
|
-
export const createTestBroker = async (port?: string | number): Promise<TestBroker> => {
|
|
19
|
-
const broker = createBroker(PublicKey.random().asBuffer(), {
|
|
20
|
-
port,
|
|
21
|
-
logger: false,
|
|
22
|
-
logLevel: 'fatal',
|
|
23
|
-
hyperswarm: { bootstrap: false }
|
|
24
|
-
});
|
|
25
|
-
await broker.start();
|
|
26
|
-
return broker;
|
|
27
|
-
};
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Copyright 2021 DXOS.org
|
|
3
|
-
//
|
|
4
|
-
|
|
5
|
-
import dht from '@hyperswarm/dht';
|
|
6
|
-
import crypto from 'crypto';
|
|
7
|
-
import internalIp from 'internal-ip';
|
|
8
|
-
import pEvent from 'p-event';
|
|
9
|
-
import publicIp from 'public-ip';
|
|
10
|
-
|
|
11
|
-
class BootstrapNode {
|
|
12
|
-
constructor (options = {}) {
|
|
13
|
-
const { port = 4000 } = options;
|
|
14
|
-
|
|
15
|
-
this._id = null;
|
|
16
|
-
this._broker = null;
|
|
17
|
-
this._port = port;
|
|
18
|
-
this._stop = false;
|
|
19
|
-
this._address = null;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
async getAddress () {
|
|
23
|
-
if (this._address) {
|
|
24
|
-
return this._address;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
if (!this._dht) {
|
|
28
|
-
throw new Error('dht not found');
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const address = this._dht.socket.address();
|
|
32
|
-
|
|
33
|
-
address.address = await this._getBootstrapIp();
|
|
34
|
-
|
|
35
|
-
this._address = address;
|
|
36
|
-
return this._address;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
async start (broker) {
|
|
40
|
-
this._broker = broker;
|
|
41
|
-
|
|
42
|
-
this._id = crypto.createHash('sha256')
|
|
43
|
-
.update(this._broker.nodeID + 'bootstrap')
|
|
44
|
-
.digest();
|
|
45
|
-
|
|
46
|
-
this._dht = dht({ ephemeral: true, adaptive: true, id: this._id });
|
|
47
|
-
|
|
48
|
-
// Runs the bootstrap UDP node in a specific port.
|
|
49
|
-
this._dht.listen(this._port);
|
|
50
|
-
|
|
51
|
-
await pEvent(this._dht, 'ready');
|
|
52
|
-
|
|
53
|
-
this._dht.on('announce', (target, peer) => {
|
|
54
|
-
this._broker.logger.debug('BOOTSTRAP_NODE: received announce', target, peer);
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
this._dht.on('unannounce', (target, peer) => {
|
|
58
|
-
this._broker.logger.debug('BOOTSTRAP_NODE: received unannounce', target, peer);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
this._dht.on('lookup', (target, peer) => {
|
|
62
|
-
this._broker.logger.debug('BOOTSTRAP_NODE: received lookup', target, peer);
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
this._dht.once('close', async () => {
|
|
66
|
-
if (this._stop) {
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
this._broker.logger.warn('BOOTSTRAP_NODE: closed, reconnecting...');
|
|
71
|
-
try {
|
|
72
|
-
await this._createBootstrapNode();
|
|
73
|
-
} catch (err) {
|
|
74
|
-
this._broker.logger.error('BOOTSTRAP_NODE: error during reconnection', err);
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
const address = await this.getAddress();
|
|
79
|
-
this._broker.logger.info('BOOTSTRAP_NODE: running on', {
|
|
80
|
-
id: this._dht.id.toString('hex'),
|
|
81
|
-
...address
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
stop () {
|
|
86
|
-
if (this._stop || this._dht.destroyed) {
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
this._stop = true;
|
|
91
|
-
if (this._dht) {
|
|
92
|
-
this._dht.destroy();
|
|
93
|
-
return pEvent(this._dht, 'close');
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
_getBootstrapIp () {
|
|
98
|
-
if (!this._dht) {
|
|
99
|
-
throw new Error('dht not found');
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
return publicIp.v4().catch(() => {
|
|
103
|
-
this._broker.logger.error('BOOTSTRAP_NODE: error trying to get external ip');
|
|
104
|
-
return internalIp.v4();
|
|
105
|
-
}).catch(err => {
|
|
106
|
-
this._broker.logger.error('BOOTSTRAP_NODE: error trying to get interal ip');
|
|
107
|
-
throw err;
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
module.exports = { BootstrapNode };
|