@dxos/signal 2.33.9-dev.d0ae5f95 → 2.33.9-dev.d0dce35f
Sign up to get free protection for your applications and to get access to all the features.
- package/.eslintrc.js +6 -0
- package/.rush/temp/package-deps_build.json +17 -0
- package/.rush/temp/package-deps_build_test.json +17 -0
- package/.rush/temp/shrinkwrap-deps.json +296 -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 +0 -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 };
|