@streamr/dht 100.0.0-testnet-three.6 → 100.1.0
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/README.md +1 -1
- package/dist/package.json +12 -8
- package/dist/src/connection/ConnectionLockRpcLocal.d.ts +1 -1
- package/dist/src/connection/ConnectionLockRpcRemote.d.ts +1 -1
- package/dist/src/connection/ConnectionLockRpcRemote.js +1 -1
- package/dist/src/connection/ConnectionLockRpcRemote.js.map +1 -1
- package/dist/src/connection/{ConnectionLockHandler.d.ts → ConnectionLockStates.d.ts} +3 -3
- package/dist/src/connection/{ConnectionLockHandler.js → ConnectionLockStates.js} +17 -9
- package/dist/src/connection/ConnectionLockStates.js.map +1 -0
- package/dist/src/connection/ConnectionManager.d.ts +9 -7
- package/dist/src/connection/ConnectionManager.js +16 -18
- package/dist/src/connection/ConnectionManager.js.map +1 -1
- package/dist/src/connection/ConnectorFacade.js +1 -1
- package/dist/src/connection/ConnectorFacade.js.map +1 -1
- package/dist/src/connection/Handshaker.js +6 -13
- package/dist/src/connection/Handshaker.js.map +1 -1
- package/dist/src/connection/ManagedConnection.d.ts +2 -2
- package/dist/src/connection/ManagedConnection.js +8 -8
- package/dist/src/connection/ManagedConnection.js.map +1 -1
- package/dist/src/connection/connectivityChecker.d.ts +1 -1
- package/dist/src/connection/connectivityChecker.js +8 -8
- package/dist/src/connection/connectivityChecker.js.map +1 -1
- package/dist/src/connection/connectivityRequestHandler.d.ts +2 -2
- package/dist/src/connection/connectivityRequestHandler.js +10 -11
- package/dist/src/connection/connectivityRequestHandler.js.map +1 -1
- package/dist/src/connection/webrtc/WebrtcConnector.d.ts +1 -0
- package/dist/src/connection/webrtc/WebrtcConnector.js +13 -8
- package/dist/src/connection/webrtc/WebrtcConnector.js.map +1 -1
- package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.d.ts +2 -0
- package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.js +4 -6
- package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.js.map +1 -1
- package/dist/src/connection/websocket/AbstractWebsocketClientConnection.d.ts +28 -0
- package/dist/src/connection/websocket/{ClientWebsocket.js → AbstractWebsocketClientConnection.js} +42 -68
- package/dist/src/connection/websocket/AbstractWebsocketClientConnection.js.map +1 -0
- package/dist/src/connection/websocket/NodeWebsocketClientConnection.d.ts +7 -0
- package/dist/src/connection/websocket/NodeWebsocketClientConnection.js +39 -0
- package/dist/src/connection/websocket/NodeWebsocketClientConnection.js.map +1 -0
- package/dist/src/connection/websocket/WebsocketConnector.js +26 -23
- package/dist/src/connection/websocket/WebsocketConnector.js.map +1 -1
- package/dist/src/connection/websocket/WebsocketServer.js +25 -35
- package/dist/src/connection/websocket/WebsocketServer.js.map +1 -1
- package/dist/src/connection/websocket/{ServerWebsocket.d.ts → WebsocketServerConnection.d.ts} +4 -5
- package/dist/src/connection/websocket/{ServerWebsocket.js → WebsocketServerConnection.js} +18 -51
- package/dist/src/connection/websocket/WebsocketServerConnection.js.map +1 -0
- package/dist/src/dht/DhtNode.d.ts +15 -8
- package/dist/src/dht/DhtNode.js +62 -31
- package/dist/src/dht/DhtNode.js.map +1 -1
- package/dist/src/dht/DhtNodeRpcLocal.d.ts +5 -1
- package/dist/src/dht/DhtNodeRpcLocal.js +10 -0
- package/dist/src/dht/DhtNodeRpcLocal.js.map +1 -1
- package/dist/src/dht/DhtNodeRpcRemote.d.ts +3 -0
- package/dist/src/dht/DhtNodeRpcRemote.js +16 -1
- package/dist/src/dht/DhtNodeRpcRemote.js.map +1 -1
- package/dist/src/dht/ExternalApiRpcLocal.d.ts +2 -2
- package/dist/src/dht/ExternalApiRpcLocal.js +3 -3
- package/dist/src/dht/ExternalApiRpcLocal.js.map +1 -1
- package/dist/src/dht/ExternalApiRpcRemote.d.ts +1 -1
- package/dist/src/dht/ExternalApiRpcRemote.js +2 -2
- package/dist/src/dht/ExternalApiRpcRemote.js.map +1 -1
- package/dist/src/dht/PeerManager.d.ts +15 -3
- package/dist/src/dht/PeerManager.js +54 -40
- package/dist/src/dht/PeerManager.js.map +1 -1
- package/dist/src/dht/contact/RingContactList.d.ts +31 -0
- package/dist/src/dht/contact/RingContactList.js +133 -0
- package/dist/src/dht/contact/RingContactList.js.map +1 -0
- package/dist/src/dht/contact/SortedContactList.d.ts +2 -1
- package/dist/src/dht/contact/SortedContactList.js +19 -17
- package/dist/src/dht/contact/SortedContactList.js.map +1 -1
- package/dist/src/dht/contact/ringIdentifiers.d.ts +16 -0
- package/dist/src/dht/contact/ringIdentifiers.js +54 -0
- package/dist/src/dht/contact/ringIdentifiers.js.map +1 -0
- package/dist/src/dht/discovery/DiscoverySession.js +3 -1
- package/dist/src/dht/discovery/DiscoverySession.js.map +1 -1
- package/dist/src/dht/discovery/PeerDiscovery.d.ts +6 -2
- package/dist/src/dht/discovery/PeerDiscovery.js +41 -4
- package/dist/src/dht/discovery/PeerDiscovery.js.map +1 -1
- package/dist/src/dht/discovery/RingDiscoverySession.d.ts +29 -0
- package/dist/src/dht/discovery/RingDiscoverySession.js +125 -0
- package/dist/src/dht/discovery/RingDiscoverySession.js.map +1 -0
- package/dist/src/dht/recursive-operation/RecursiveOperationManager.js +1 -1
- package/dist/src/dht/recursive-operation/RecursiveOperationManager.js.map +1 -1
- package/dist/src/dht/recursive-operation/RecursiveOperationRpcRemote.js +1 -1
- package/dist/src/dht/recursive-operation/RecursiveOperationRpcRemote.js.map +1 -1
- package/dist/src/dht/recursive-operation/RecursiveOperationSession.js +0 -1
- package/dist/src/dht/recursive-operation/RecursiveOperationSession.js.map +1 -1
- package/dist/src/dht/routing/Router.d.ts +0 -1
- package/dist/src/dht/routing/Router.js +0 -1
- package/dist/src/dht/routing/Router.js.map +1 -1
- package/dist/src/dht/routing/RouterRpcLocal.d.ts +0 -1
- package/dist/src/dht/routing/RouterRpcLocal.js.map +1 -1
- package/dist/src/dht/routing/RouterRpcRemote.js +2 -2
- package/dist/src/dht/routing/RouterRpcRemote.js.map +1 -1
- package/dist/src/dht/routing/RoutingSession.js +2 -2
- package/dist/src/dht/routing/RoutingSession.js.map +1 -1
- package/dist/src/dht/store/LocalDataStore.js +2 -2
- package/dist/src/dht/store/LocalDataStore.js.map +1 -1
- package/dist/src/dht/store/StoreManager.js +2 -2
- package/dist/src/dht/store/StoreManager.js.map +1 -1
- package/dist/src/exports.d.ts +3 -2
- package/dist/src/exports.js +3 -3
- package/dist/src/exports.js.map +1 -1
- package/dist/src/helpers/createPeerDescriptor.d.ts +1 -1
- package/dist/src/helpers/createPeerDescriptor.js +2 -1
- package/dist/src/helpers/createPeerDescriptor.js.map +1 -1
- package/dist/src/helpers/version.d.ts +6 -0
- package/dist/src/helpers/version.js +38 -0
- package/dist/src/helpers/version.js.map +1 -0
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.d.ts +16 -6
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.js +11 -4
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.d.ts +98 -87
- package/dist/src/proto/packages/dht/protos/DhtRpc.js +45 -49
- package/dist/src/proto/packages/dht/protos/DhtRpc.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.server.d.ts +10 -4
- package/dist/src/transport/RoutingRpcCommunicator.js +0 -2
- package/dist/src/transport/RoutingRpcCommunicator.js.map +1 -1
- package/karma.config.js +4 -1
- package/package.json +12 -8
- package/protos/DhtRpc.proto +21 -21
- package/src/connection/ConnectionLockRpcLocal.ts +1 -1
- package/src/connection/ConnectionLockRpcRemote.ts +2 -2
- package/src/connection/{ConnectionLockHandler.ts → ConnectionLockStates.ts} +14 -6
- package/src/connection/ConnectionManager.ts +21 -22
- package/src/connection/ConnectorFacade.ts +1 -2
- package/src/connection/Handshaker.ts +7 -15
- package/src/connection/ManagedConnection.ts +8 -8
- package/src/connection/connectivityChecker.ts +9 -10
- package/src/connection/connectivityRequestHandler.ts +16 -16
- package/src/connection/webrtc/BrowserWebrtcConnection.ts +18 -0
- package/src/connection/webrtc/NodeWebrtcConnection.ts +1 -1
- package/src/connection/webrtc/WebrtcConnector.ts +14 -8
- package/src/connection/webrtc/WebrtcConnectorRpcLocal.ts +5 -5
- package/src/connection/websocket/{ClientWebsocket.ts → AbstractWebsocketClientConnection.ts} +57 -70
- package/src/connection/websocket/BrowserWebsocketClientConnection.ts +44 -0
- package/src/connection/websocket/NodeWebsocketClientConnection.ts +39 -0
- package/src/connection/websocket/WebsocketConnector.ts +27 -28
- package/src/connection/websocket/WebsocketServer.ts +27 -42
- package/src/connection/websocket/{ServerWebsocket.ts → WebsocketServerConnection.ts} +15 -56
- package/src/dht/DhtNode.ts +85 -50
- package/src/dht/DhtNodeRpcLocal.ts +16 -0
- package/src/dht/DhtNodeRpcRemote.ts +19 -1
- package/src/dht/ExternalApiRpcLocal.ts +5 -5
- package/src/dht/ExternalApiRpcRemote.ts +4 -4
- package/src/dht/PeerManager.ts +70 -44
- package/src/dht/contact/RingContactList.ts +151 -0
- package/src/dht/contact/SortedContactList.ts +22 -18
- package/src/dht/contact/ringIdentifiers.ts +62 -0
- package/src/dht/discovery/DiscoverySession.ts +3 -1
- package/src/dht/discovery/PeerDiscovery.ts +45 -6
- package/src/dht/discovery/RingDiscoverySession.ts +162 -0
- package/src/dht/recursive-operation/RecursiveOperationManager.ts +1 -1
- package/src/dht/recursive-operation/RecursiveOperationRpcRemote.ts +1 -1
- package/src/dht/recursive-operation/RecursiveOperationSession.ts +1 -3
- package/src/dht/routing/Router.ts +0 -2
- package/src/dht/routing/RouterRpcLocal.ts +0 -1
- package/src/dht/routing/RouterRpcRemote.ts +2 -2
- package/src/dht/routing/RoutingSession.ts +2 -2
- package/src/dht/store/LocalDataStore.ts +1 -1
- package/src/dht/store/StoreManager.ts +2 -2
- package/src/exports.ts +3 -2
- package/src/helpers/createPeerDescriptor.ts +2 -1
- package/src/helpers/version.ts +32 -0
- package/src/proto/packages/dht/protos/DhtRpc.client.ts +22 -9
- package/src/proto/packages/dht/protos/DhtRpc.server.ts +10 -4
- package/src/proto/packages/dht/protos/DhtRpc.ts +122 -100
- package/src/transport/RoutingRpcCommunicator.ts +1 -2
- package/test/benchmark/Find.test.ts +3 -4
- package/test/benchmark/KademliaCorrectness.test.ts +14 -8
- package/test/benchmark/RingCorrectness.test.ts +157 -0
- package/test/benchmark/WebsocketServerMemoryLeak.test.ts +2 -2
- package/test/benchmark/hybrid-network-simulation/RingContactList.test.ts +72 -0
- package/test/data/generateGroundTruthData.ts +2 -2
- package/test/end-to-end/memory-leak.test.ts +1 -2
- package/test/integration/ConnectionManager.test.ts +28 -10
- package/test/integration/ConnectivityChecking.test.ts +3 -15
- package/test/integration/DhtNodeExternalAPI.test.ts +6 -6
- package/test/integration/Find.test.ts +6 -6
- package/test/integration/Layer1-scale.test.ts +0 -1
- package/test/integration/ReplicateData.test.ts +4 -4
- package/test/integration/RouteMessage.test.ts +1 -6
- package/test/integration/RouterRpcRemote.test.ts +1 -3
- package/test/integration/SimultaneousConnections.test.ts +9 -10
- package/test/integration/Store.test.ts +4 -4
- package/test/integration/StoreAndDelete.test.ts +5 -5
- package/test/integration/StoreOnDhtWithThreeNodes.test.ts +5 -5
- package/test/integration/StoreOnDhtWithTwoNodes.test.ts +3 -3
- package/test/integration/WebrtcConnectionManagement.test.ts +3 -9
- package/test/integration/Websocket.test.ts +2 -2
- package/test/integration/WebsocketConnectionManagement.test.ts +1 -6
- package/test/integration/rpc-connections-over-webrpc.test.ts +1 -2
- package/test/unit/PeerManager.test.ts +44 -10
- package/test/unit/RecursiveOperationManager.test.ts +14 -8
- package/test/unit/RecursiveOperationSession.test.ts +1 -1
- package/test/unit/Router.test.ts +0 -3
- package/test/unit/RoutingSession.test.ts +1 -2
- package/test/unit/connectivityRequestHandler.test.ts +5 -9
- package/test/unit/createPeerDescriptor.test.ts +12 -6
- package/test/unit/version.test.ts +18 -0
- package/test/utils/utils.ts +60 -47
- package/tsconfig.browser.json +2 -1
- package/tsconfig.jest.json +4 -2
- package/tsconfig.node.json +4 -2
- package/dist/src/connection/ConnectionLockHandler.js.map +0 -1
- package/dist/src/connection/websocket/ClientWebsocket.d.ts +0 -17
- package/dist/src/connection/websocket/ClientWebsocket.js.map +0 -1
- package/dist/src/connection/websocket/ServerWebsocket.js.map +0 -1
- package/dist/src/helpers/MapWithTtl.d.ts +0 -14
- package/dist/src/helpers/MapWithTtl.js +0 -60
- package/dist/src/helpers/MapWithTtl.js.map +0 -1
- package/dist/src/helpers/versionCompatibility.d.ts +0 -2
- package/dist/src/helpers/versionCompatibility.js +0 -18
- package/dist/src/helpers/versionCompatibility.js.map +0 -1
- package/src/helpers/MapWithTtl.ts +0 -71
- package/src/helpers/versionCompatibility.ts +0 -13
- package/test/unit/versionCompatibility.test.ts +0 -16
|
@@ -35,7 +35,7 @@ export class ManagedConnection extends EventEmitter<Events> {
|
|
|
35
35
|
public connectionType: ConnectionType
|
|
36
36
|
private handshaker?: Handshaker
|
|
37
37
|
private handshakeCompleted = false
|
|
38
|
-
private
|
|
38
|
+
private lastUsedTimestamp: number = Date.now()
|
|
39
39
|
private stopped = false
|
|
40
40
|
private bufferSentbyOtherConnection = false
|
|
41
41
|
private closing = false
|
|
@@ -160,8 +160,8 @@ export class ManagedConnection extends EventEmitter<Events> {
|
|
|
160
160
|
return getNodeIdFromPeerDescriptor(this.remotePeerDescriptor!)
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
public
|
|
164
|
-
return this.
|
|
163
|
+
public getLastUsedTimestamp(): number {
|
|
164
|
+
return this.lastUsedTimestamp
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
public setRemotePeerDescriptor(peerDescriptor: PeerDescriptor): void {
|
|
@@ -173,7 +173,7 @@ export class ManagedConnection extends EventEmitter<Events> {
|
|
|
173
173
|
}
|
|
174
174
|
|
|
175
175
|
private onHandshakeCompleted(peerDescriptor: PeerDescriptor) {
|
|
176
|
-
this.
|
|
176
|
+
this.lastUsedTimestamp = Date.now()
|
|
177
177
|
|
|
178
178
|
this.setRemotePeerDescriptor(peerDescriptor)
|
|
179
179
|
this.handshakeCompleted = true
|
|
@@ -193,7 +193,7 @@ export class ManagedConnection extends EventEmitter<Events> {
|
|
|
193
193
|
this.implementation = impl
|
|
194
194
|
|
|
195
195
|
impl.on('data', (bytes: Uint8Array) => {
|
|
196
|
-
this.
|
|
196
|
+
this.lastUsedTimestamp = Date.now()
|
|
197
197
|
if (this.listenerCount('managedData') === 0) {
|
|
198
198
|
this.inputBuffer.push(bytes)
|
|
199
199
|
} else {
|
|
@@ -205,7 +205,7 @@ export class ManagedConnection extends EventEmitter<Events> {
|
|
|
205
205
|
this.emit('error', name)
|
|
206
206
|
})
|
|
207
207
|
impl.on('connected', () => {
|
|
208
|
-
this.
|
|
208
|
+
this.lastUsedTimestamp = Date.now()
|
|
209
209
|
logger.trace('connected emitted')
|
|
210
210
|
this.emit('connected')
|
|
211
211
|
})
|
|
@@ -231,7 +231,7 @@ export class ManagedConnection extends EventEmitter<Events> {
|
|
|
231
231
|
if (this.closing) {
|
|
232
232
|
throw new Err.SendFailed('ManagedConnection is closing')
|
|
233
233
|
}
|
|
234
|
-
this.
|
|
234
|
+
this.lastUsedTimestamp = Date.now()
|
|
235
235
|
|
|
236
236
|
if (!connect && !this.implementation) {
|
|
237
237
|
throw new Err.ConnectionNotOpen('Connection not open when calling send() with connect flag as false')
|
|
@@ -263,7 +263,7 @@ export class ManagedConnection extends EventEmitter<Events> {
|
|
|
263
263
|
}
|
|
264
264
|
|
|
265
265
|
public sendNoWait(data: Uint8Array): void {
|
|
266
|
-
this.
|
|
266
|
+
this.lastUsedTimestamp = Date.now()
|
|
267
267
|
if (this.implementation) {
|
|
268
268
|
this.implementation.send(data)
|
|
269
269
|
} else {
|
|
@@ -3,12 +3,12 @@ import { v4 } from 'uuid'
|
|
|
3
3
|
import * as Err from '../helpers/errors'
|
|
4
4
|
import {
|
|
5
5
|
ConnectivityRequest, ConnectivityResponse,
|
|
6
|
-
Message,
|
|
6
|
+
Message, PeerDescriptor
|
|
7
7
|
} from '../proto/packages/dht/protos/DhtRpc'
|
|
8
8
|
import { ConnectionEvents, IConnection } from './IConnection'
|
|
9
|
-
import {
|
|
9
|
+
import { WebsocketClientConnection } from './websocket/NodeWebsocketClientConnection'
|
|
10
10
|
import { connectivityMethodToWebsocketUrl } from './websocket/WebsocketConnector'
|
|
11
|
-
import {
|
|
11
|
+
import { isMaybeSupportedVersion } from '../helpers/version'
|
|
12
12
|
|
|
13
13
|
const logger = new Logger(module)
|
|
14
14
|
|
|
@@ -16,7 +16,7 @@ const logger = new Logger(module)
|
|
|
16
16
|
export const connectAsync = async ({ url, selfSigned, timeoutMs = 1000 }:
|
|
17
17
|
{ url: string, selfSigned: boolean, timeoutMs?: number }
|
|
18
18
|
): Promise<IConnection> => {
|
|
19
|
-
const socket = new
|
|
19
|
+
const socket = new WebsocketClientConnection()
|
|
20
20
|
let result: RunAndRaceEventsReturnType<ConnectionEvents>
|
|
21
21
|
try {
|
|
22
22
|
result = await runAndRaceEvents3<ConnectionEvents>([
|
|
@@ -37,8 +37,7 @@ const CONNECTIVITY_CHECKER_TIMEOUT = 5000
|
|
|
37
37
|
|
|
38
38
|
export const sendConnectivityRequest = async (
|
|
39
39
|
request: ConnectivityRequest,
|
|
40
|
-
entryPoint: PeerDescriptor
|
|
41
|
-
localVersion: string
|
|
40
|
+
entryPoint: PeerDescriptor
|
|
42
41
|
): Promise<ConnectivityResponse> => {
|
|
43
42
|
let outgoingConnection: IConnection
|
|
44
43
|
const wsServerInfo = {
|
|
@@ -59,7 +58,7 @@ export const sendConnectivityRequest = async (
|
|
|
59
58
|
// send connectivity request
|
|
60
59
|
const msg: Message = {
|
|
61
60
|
serviceId: CONNECTIVITY_CHECKER_SERVICE_ID,
|
|
62
|
-
|
|
61
|
+
messageId: v4(),
|
|
63
62
|
body: {
|
|
64
63
|
oneofKind: 'connectivityRequest',
|
|
65
64
|
connectivityRequest: request
|
|
@@ -83,16 +82,16 @@ export const sendConnectivityRequest = async (
|
|
|
83
82
|
const remoteVersion = connectivityResponseMessage.version
|
|
84
83
|
outgoingConnection!.off('data', listener)
|
|
85
84
|
clearTimeout(timeoutId)
|
|
86
|
-
if (
|
|
85
|
+
if (isMaybeSupportedVersion(remoteVersion)) {
|
|
87
86
|
resolve(connectivityResponseMessage)
|
|
88
87
|
} else {
|
|
89
|
-
reject(`
|
|
88
|
+
reject(`Unsupported version: ${remoteVersion}`)
|
|
90
89
|
}
|
|
91
90
|
} else {
|
|
92
91
|
return
|
|
93
92
|
}
|
|
94
93
|
} catch (err) {
|
|
95
|
-
logger.trace(
|
|
94
|
+
logger.trace('Could not parse message', { err })
|
|
96
95
|
}
|
|
97
96
|
}
|
|
98
97
|
outgoingConnection!.on('data', listener)
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
import { ipv4ToNumber, Logger } from '@streamr/utils'
|
|
2
2
|
import { v4 } from 'uuid'
|
|
3
3
|
import {
|
|
4
|
-
ConnectivityRequest,
|
|
5
|
-
|
|
4
|
+
ConnectivityRequest,
|
|
5
|
+
ConnectivityResponse,
|
|
6
|
+
Message
|
|
6
7
|
} from '../proto/packages/dht/protos/DhtRpc'
|
|
7
8
|
import { NatType } from './ConnectionManager'
|
|
8
9
|
import { CONNECTIVITY_CHECKER_SERVICE_ID, connectAsync } from './connectivityChecker'
|
|
9
10
|
import { IConnection } from './IConnection'
|
|
10
|
-
import {
|
|
11
|
+
import { WebsocketServerConnection } from './websocket/WebsocketServerConnection'
|
|
11
12
|
import { connectivityMethodToWebsocketUrl } from './websocket/WebsocketConnector'
|
|
12
|
-
import {
|
|
13
|
+
import { LOCAL_PROTOCOL_VERSION } from '../helpers/version'
|
|
13
14
|
|
|
14
15
|
export const DISABLE_CONNECTIVITY_PROBE = 0
|
|
15
16
|
|
|
16
17
|
const logger = new Logger(module)
|
|
17
18
|
|
|
18
|
-
export const attachConnectivityRequestHandler = (connectionToListenTo:
|
|
19
|
+
export const attachConnectivityRequestHandler = (connectionToListenTo: WebsocketServerConnection): void => {
|
|
19
20
|
connectionToListenTo.on('data', async (data: Uint8Array) => {
|
|
20
21
|
logger.trace('server received data')
|
|
21
22
|
try {
|
|
@@ -25,19 +26,19 @@ export const attachConnectivityRequestHandler = (connectionToListenTo: ServerWeb
|
|
|
25
26
|
try {
|
|
26
27
|
await handleIncomingConnectivityRequest(connectionToListenTo, message.body.connectivityRequest)
|
|
27
28
|
logger.trace('handleIncomingConnectivityRequest ok')
|
|
28
|
-
} catch (
|
|
29
|
-
logger.error('handleIncomingConnectivityRequest', {
|
|
29
|
+
} catch (err1) {
|
|
30
|
+
logger.error('handleIncomingConnectivityRequest', { err: err1 })
|
|
30
31
|
}
|
|
31
32
|
}
|
|
32
|
-
} catch (
|
|
33
|
-
logger.trace(
|
|
33
|
+
} catch (err2) {
|
|
34
|
+
logger.trace('Could not parse message', { err: err2 })
|
|
34
35
|
}
|
|
35
36
|
})
|
|
36
37
|
}
|
|
37
38
|
|
|
38
|
-
const handleIncomingConnectivityRequest = async (connection:
|
|
39
|
-
const host = connectivityRequest.host ?? connection.
|
|
40
|
-
const ipAddress = connection.
|
|
39
|
+
const handleIncomingConnectivityRequest = async (connection: WebsocketServerConnection, connectivityRequest: ConnectivityRequest): Promise<void> => {
|
|
40
|
+
const host = connectivityRequest.host ?? connection.remoteIpAddress
|
|
41
|
+
const ipAddress = connection.remoteIpAddress
|
|
41
42
|
let connectivityResponse: ConnectivityResponse
|
|
42
43
|
if (connectivityRequest.port !== DISABLE_CONNECTIVITY_PROBE) {
|
|
43
44
|
connectivityResponse = await connectivityProbe(connectivityRequest, ipAddress, host)
|
|
@@ -47,12 +48,11 @@ const handleIncomingConnectivityRequest = async (connection: ServerWebsocket, co
|
|
|
47
48
|
host,
|
|
48
49
|
natType: NatType.UNKNOWN,
|
|
49
50
|
ipAddress: ipv4ToNumber(ipAddress),
|
|
50
|
-
version:
|
|
51
|
+
version: LOCAL_PROTOCOL_VERSION
|
|
51
52
|
}
|
|
52
53
|
}
|
|
53
54
|
const msg: Message = {
|
|
54
55
|
serviceId: CONNECTIVITY_CHECKER_SERVICE_ID,
|
|
55
|
-
messageType: MessageType.CONNECTIVITY_RESPONSE,
|
|
56
56
|
messageId: v4(),
|
|
57
57
|
body: {
|
|
58
58
|
oneofKind: 'connectivityResponse',
|
|
@@ -84,7 +84,7 @@ const connectivityProbe = async (connectivityRequest: ConnectivityRequest, ipAdd
|
|
|
84
84
|
natType: NatType.OPEN_INTERNET,
|
|
85
85
|
websocket: { host, port: connectivityRequest.port, tls: connectivityRequest.tls },
|
|
86
86
|
ipAddress: ipv4ToNumber(ipAddress),
|
|
87
|
-
version:
|
|
87
|
+
version: LOCAL_PROTOCOL_VERSION
|
|
88
88
|
}
|
|
89
89
|
} catch (err) {
|
|
90
90
|
logger.debug('error', { err })
|
|
@@ -92,7 +92,7 @@ const connectivityProbe = async (connectivityRequest: ConnectivityRequest, ipAdd
|
|
|
92
92
|
host,
|
|
93
93
|
natType: NatType.UNKNOWN,
|
|
94
94
|
ipAddress: ipv4ToNumber(ipAddress),
|
|
95
|
-
version:
|
|
95
|
+
version: LOCAL_PROTOCOL_VERSION
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
if (outgoingConnection) {
|
|
@@ -5,6 +5,12 @@ import { Logger } from '@streamr/utils'
|
|
|
5
5
|
import { IceServer } from './WebrtcConnector'
|
|
6
6
|
import { createRandomConnectionId } from '../Connection'
|
|
7
7
|
|
|
8
|
+
enum DisconnectedRtcPeerConnectionStateEnum {
|
|
9
|
+
DISCONNECTED = 'disconnected',
|
|
10
|
+
FAILED = 'failed',
|
|
11
|
+
CLOSED = 'closed',
|
|
12
|
+
}
|
|
13
|
+
|
|
8
14
|
const logger = new Logger(module)
|
|
9
15
|
|
|
10
16
|
export const WEBRTC_CLEANUP = new class {
|
|
@@ -58,6 +64,8 @@ export class NodeWebrtcConnection extends EventEmitter<Events> implements IWebrt
|
|
|
58
64
|
logger.trace(`conn.onGatheringStateChange: ${this.peerConnection?.iceGatheringState}`)
|
|
59
65
|
}
|
|
60
66
|
|
|
67
|
+
this.peerConnection.onconnectionstatechange = () => this.onStateChange()
|
|
68
|
+
|
|
61
69
|
if (isOffering) {
|
|
62
70
|
this.peerConnection.onnegotiationneeded = async () => {
|
|
63
71
|
try {
|
|
@@ -211,6 +219,7 @@ export class NodeWebrtcConnection extends EventEmitter<Events> implements IWebrt
|
|
|
211
219
|
}
|
|
212
220
|
|
|
213
221
|
if (this.peerConnection !== undefined) {
|
|
222
|
+
this.peerConnection.onconnectionstatechange = null
|
|
214
223
|
this.peerConnection.onicecandidate = null
|
|
215
224
|
this.peerConnection.onicegatheringstatechange = null
|
|
216
225
|
this.peerConnection.onnegotiationneeded = null
|
|
@@ -223,6 +232,15 @@ export class NodeWebrtcConnection extends EventEmitter<Events> implements IWebrt
|
|
|
223
232
|
this.emit('connected')
|
|
224
233
|
}
|
|
225
234
|
|
|
235
|
+
private onStateChange(): void {
|
|
236
|
+
if (this.peerConnection!.connectionState === DisconnectedRtcPeerConnectionStateEnum.CLOSED
|
|
237
|
+
|| this.peerConnection!.connectionState === DisconnectedRtcPeerConnectionStateEnum.DISCONNECTED
|
|
238
|
+
|| this.peerConnection!.connectionState === DisconnectedRtcPeerConnectionStateEnum.FAILED
|
|
239
|
+
) {
|
|
240
|
+
this.doClose(false)
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
226
244
|
public setConnectionId(connectionId: ConnectionID): void {
|
|
227
245
|
this.connectionId = connectionId
|
|
228
246
|
}
|
|
@@ -26,7 +26,7 @@ export interface Params {
|
|
|
26
26
|
bufferThresholdLow?: number
|
|
27
27
|
connectingTimeout?: number
|
|
28
28
|
maxMessageSize?: number
|
|
29
|
-
iceServers?: IceServer[]
|
|
29
|
+
iceServers?: IceServer[] // TODO make this parameter required (empty array is a good fallback which can be set by the caller if needed)
|
|
30
30
|
portRange?: PortRange
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -75,6 +75,7 @@ export class WebrtcConnector {
|
|
|
75
75
|
onNewConnection: (connection: ManagedConnection) => boolean
|
|
76
76
|
) {
|
|
77
77
|
const localRpc = new WebrtcConnectorRpcLocal({
|
|
78
|
+
createConnection: (targetPeerDescriptor: PeerDescriptor) => this.createConnection(targetPeerDescriptor),
|
|
78
79
|
connect: (targetPeerDescriptor: PeerDescriptor) => this.connect(targetPeerDescriptor),
|
|
79
80
|
onNewConnection,
|
|
80
81
|
ongoingConnectAttempts: this.ongoingConnectAttempts,
|
|
@@ -133,14 +134,7 @@ export class WebrtcConnector {
|
|
|
133
134
|
return existingConnection
|
|
134
135
|
}
|
|
135
136
|
|
|
136
|
-
const connection =
|
|
137
|
-
remotePeerDescriptor: targetPeerDescriptor,
|
|
138
|
-
iceServers: this.config.iceServers,
|
|
139
|
-
bufferThresholdLow: this.config.bufferThresholdLow,
|
|
140
|
-
bufferThresholdHigh: this.config.bufferThresholdHigh,
|
|
141
|
-
connectingTimeout: this.config.connectionTimeout,
|
|
142
|
-
portRange: this.config.portRange
|
|
143
|
-
})
|
|
137
|
+
const connection = this.createConnection(targetPeerDescriptor)
|
|
144
138
|
|
|
145
139
|
const localNodeId = getNodeIdFromPeerDescriptor(this.localPeerDescriptor!)
|
|
146
140
|
const targetNodeId = getNodeIdFromPeerDescriptor(targetPeerDescriptor)
|
|
@@ -199,6 +193,18 @@ export class WebrtcConnector {
|
|
|
199
193
|
return managedConnection
|
|
200
194
|
}
|
|
201
195
|
|
|
196
|
+
private createConnection(targetPeerDescriptor: PeerDescriptor): NodeWebrtcConnection {
|
|
197
|
+
return new NodeWebrtcConnection({
|
|
198
|
+
remotePeerDescriptor: targetPeerDescriptor,
|
|
199
|
+
iceServers: this.config.iceServers,
|
|
200
|
+
bufferThresholdLow: this.config.bufferThresholdLow,
|
|
201
|
+
bufferThresholdHigh: this.config.bufferThresholdHigh,
|
|
202
|
+
connectingTimeout: this.config.connectionTimeout,
|
|
203
|
+
portRange: this.config.portRange
|
|
204
|
+
// TODO should we pass maxMessageSize?
|
|
205
|
+
})
|
|
206
|
+
}
|
|
207
|
+
|
|
202
208
|
setLocalPeerDescriptor(peerDescriptor: PeerDescriptor): void {
|
|
203
209
|
this.localPeerDescriptor = peerDescriptor
|
|
204
210
|
}
|
|
@@ -18,13 +18,13 @@ import { ManagedWebrtcConnection } from '../ManagedWebrtcConnection'
|
|
|
18
18
|
import { NodeWebrtcConnection } from './NodeWebrtcConnection'
|
|
19
19
|
import { WebrtcConnectorRpcRemote } from './WebrtcConnectorRpcRemote'
|
|
20
20
|
import { DhtAddress, getNodeIdFromPeerDescriptor } from '../../identifiers'
|
|
21
|
-
import {
|
|
22
|
-
import { isCompatibleVersion } from '../../helpers/versionCompatibility'
|
|
21
|
+
import { isMaybeSupportedVersion } from '../../helpers/version'
|
|
23
22
|
import { ConnectionID } from '../IConnection'
|
|
24
23
|
|
|
25
24
|
const logger = new Logger(module)
|
|
26
25
|
|
|
27
26
|
interface WebrtcConnectorRpcLocalConfig {
|
|
27
|
+
createConnection: (targetPeerDescriptor: PeerDescriptor) => NodeWebrtcConnection
|
|
28
28
|
connect: (targetPeerDescriptor: PeerDescriptor) => ManagedConnection
|
|
29
29
|
onNewConnection: (connection: ManagedConnection) => boolean
|
|
30
30
|
// TODO pass accessor methods instead of passing a mutable entity
|
|
@@ -60,7 +60,7 @@ export class WebrtcConnectorRpcLocal implements IWebrtcConnectorRpc {
|
|
|
60
60
|
let connection = managedConnection?.getWebrtcConnection()
|
|
61
61
|
|
|
62
62
|
if (!managedConnection) {
|
|
63
|
-
connection =
|
|
63
|
+
connection = this.config.createConnection(remotePeer)
|
|
64
64
|
managedConnection = new ManagedWebrtcConnection(this.config.getLocalPeerDescriptor(), undefined, connection)
|
|
65
65
|
managedConnection.setRemotePeerDescriptor(remotePeer)
|
|
66
66
|
this.config.ongoingConnectAttempts.set(nodeId, managedConnection)
|
|
@@ -84,11 +84,11 @@ export class WebrtcConnectorRpcLocal implements IWebrtcConnectorRpc {
|
|
|
84
84
|
connection!.setConnectionId(request.connectionId as ConnectionID)
|
|
85
85
|
connection!.setRemoteDescription(request.description, 'offer')
|
|
86
86
|
|
|
87
|
-
managedConnection.on('handshakeRequest', (_sourceDescriptor: PeerDescriptor,
|
|
87
|
+
managedConnection.on('handshakeRequest', (_sourceDescriptor: PeerDescriptor, remoteVersion: string) => {
|
|
88
88
|
if (this.config.ongoingConnectAttempts.has(nodeId)) {
|
|
89
89
|
this.config.ongoingConnectAttempts.delete(nodeId)
|
|
90
90
|
}
|
|
91
|
-
if (!
|
|
91
|
+
if (!isMaybeSupportedVersion(remoteVersion)) {
|
|
92
92
|
managedConnection!.rejectHandshake(HandshakeError.UNSUPPORTED_VERSION)
|
|
93
93
|
} else {
|
|
94
94
|
managedConnection!.acceptHandshake()
|
package/src/connection/websocket/{ClientWebsocket.ts → AbstractWebsocketClientConnection.ts}
RENAMED
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import { Logger } from '@streamr/utils'
|
|
2
1
|
import EventEmitter from 'eventemitter3'
|
|
3
|
-
import { ICloseEvent, IMessageEvent, w3cwebsocket as Websocket } from 'websocket'
|
|
4
|
-
import { ConnectionEvents, ConnectionID, ConnectionType, IConnection } from '../IConnection'
|
|
5
2
|
import { createRandomConnectionId } from '../Connection'
|
|
3
|
+
import { ConnectionEvents, ConnectionID, ConnectionType, IConnection } from '../IConnection'
|
|
4
|
+
import { Logger } from '@streamr/utils'
|
|
6
5
|
|
|
7
|
-
|
|
6
|
+
export interface Socket {
|
|
7
|
+
binaryType: string
|
|
8
|
+
readyState: number
|
|
9
|
+
close(code?: number, reason?: string): void
|
|
10
|
+
send(data: string | Buffer | ArrayBuffer | ArrayBufferView): void
|
|
11
|
+
}
|
|
8
12
|
|
|
9
13
|
// https://kapeli.com/cheat_sheets/WebSocket_Status_Codes.docset/Contents/Resources/Documents/index
|
|
10
14
|
// Browsers send this automatically when closing a tab
|
|
@@ -12,78 +16,33 @@ export const GOING_AWAY = 1001
|
|
|
12
16
|
// The GOING_AWAY is a reserved code and we shouldn't send that from the application. Therefore
|
|
13
17
|
// we have a custom counterpart
|
|
14
18
|
export const CUSTOM_GOING_AWAY = 3001
|
|
19
|
+
// https://github.com/websockets/ws/blob/master/doc/ws.md#ready-state-constants
|
|
20
|
+
const OPEN = 1
|
|
15
21
|
|
|
16
|
-
const
|
|
22
|
+
const logger = new Logger(module)
|
|
17
23
|
|
|
18
|
-
export class
|
|
24
|
+
export abstract class AbstractWebsocketClientConnection extends EventEmitter<ConnectionEvents> implements IConnection {
|
|
19
25
|
|
|
20
26
|
public readonly connectionId: ConnectionID
|
|
21
|
-
|
|
27
|
+
protected abstract socket?: Socket
|
|
22
28
|
public connectionType = ConnectionType.WEBSOCKET_CLIENT
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
29
|
+
protected destroyed = false
|
|
30
|
+
|
|
26
31
|
constructor() {
|
|
27
32
|
super()
|
|
28
33
|
this.connectionId = createRandomConnectionId()
|
|
29
34
|
}
|
|
30
35
|
|
|
31
36
|
// TODO explicit default value for "selfSigned" or make it required
|
|
32
|
-
public connect(address: string, selfSigned?: boolean): void
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
this.socket.binaryType = BINARY_TYPE
|
|
36
|
-
this.socket.onerror = (error: Error) => {
|
|
37
|
-
if (!this.destroyed) {
|
|
38
|
-
logger.trace('WebSocket Client error: ' + error?.message, { error })
|
|
39
|
-
this.emit('error', error.name)
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
this.socket.onopen = () => {
|
|
44
|
-
if (!this.destroyed) {
|
|
45
|
-
logger.trace('WebSocket Client Connected')
|
|
46
|
-
if (this.socket && this.socket.readyState === this.socket.OPEN) {
|
|
47
|
-
this.emit('connected')
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
this.socket.onclose = (event: ICloseEvent) => {
|
|
53
|
-
if (!this.destroyed) {
|
|
54
|
-
logger.trace('Websocket Closed')
|
|
55
|
-
this.doDisconnect(event.code, event.reason)
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
this.socket.onmessage = (message: IMessageEvent) => {
|
|
60
|
-
if (!this.destroyed) {
|
|
61
|
-
if (typeof message.data === 'string') {
|
|
62
|
-
logger.debug('Received string: \'' + message.data + '\'')
|
|
63
|
-
} else {
|
|
64
|
-
this.emit('data', new Uint8Array(message.data))
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
} else {
|
|
69
|
-
logger.debug('Tried to connect() a stopped connection')
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
private doDisconnect(code?: number, reason?: string) {
|
|
74
|
-
this.destroyed = true
|
|
75
|
-
this.stopListening()
|
|
76
|
-
this.socket = undefined
|
|
77
|
-
const gracefulLeave = (code === GOING_AWAY) || (code === CUSTOM_GOING_AWAY)
|
|
78
|
-
this.emit('disconnected', gracefulLeave, code, reason)
|
|
79
|
-
this.removeAllListeners()
|
|
80
|
-
}
|
|
37
|
+
public abstract connect(address: string, selfSigned?: boolean): void
|
|
38
|
+
|
|
39
|
+
protected abstract stopListening(): void
|
|
81
40
|
|
|
82
41
|
public send(data: Uint8Array): void {
|
|
83
42
|
if (!this.destroyed) {
|
|
84
|
-
if (this.socket && this.socket.readyState ===
|
|
43
|
+
if (this.socket && this.socket.readyState === OPEN) {
|
|
85
44
|
logger.trace(`Sending data with size ${data.byteLength}`)
|
|
86
|
-
this.socket?.send(data
|
|
45
|
+
this.socket?.send(data)
|
|
87
46
|
} else {
|
|
88
47
|
logger.debug('Tried to send data on a non-open connection')
|
|
89
48
|
}
|
|
@@ -103,15 +62,6 @@ export class ClientWebsocket extends EventEmitter<ConnectionEvents> implements I
|
|
|
103
62
|
}
|
|
104
63
|
}
|
|
105
64
|
|
|
106
|
-
private stopListening(): void {
|
|
107
|
-
if (this.socket) {
|
|
108
|
-
this.socket.onopen = undefined as unknown as (() => void)
|
|
109
|
-
this.socket.onclose = undefined as unknown as (() => void)
|
|
110
|
-
this.socket.onerror = undefined as unknown as (() => void)
|
|
111
|
-
this.socket.onmessage = undefined as unknown as (() => void)
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
65
|
public destroy(): void {
|
|
116
66
|
logger.trace('destroy() a connection')
|
|
117
67
|
if (!this.destroyed) {
|
|
@@ -126,4 +76,41 @@ export class ClientWebsocket extends EventEmitter<ConnectionEvents> implements I
|
|
|
126
76
|
logger.debug('Tried to destroy() a stopped connection')
|
|
127
77
|
}
|
|
128
78
|
}
|
|
79
|
+
|
|
80
|
+
protected onOpen(): void {
|
|
81
|
+
if (!this.destroyed) {
|
|
82
|
+
logger.trace('WebSocket Client Connected')
|
|
83
|
+
if (this.socket && this.socket.readyState === OPEN) {
|
|
84
|
+
this.emit('connected')
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
protected onMessage(message: Uint8Array): void {
|
|
90
|
+
this.emit('data', message)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
protected onClose(code: number, reason: string): void {
|
|
94
|
+
if (!this.destroyed) {
|
|
95
|
+
logger.trace('Websocket Closed')
|
|
96
|
+
this.doDisconnect(code, reason)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
protected onError(error: Error): void {
|
|
101
|
+
if (!this.destroyed) {
|
|
102
|
+
logger.trace('WebSocket Client error: ' + error?.message, { error })
|
|
103
|
+
this.emit('error', error.name)
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
protected doDisconnect(code?: number, reason?: string): void {
|
|
108
|
+
this.destroyed = true
|
|
109
|
+
this.stopListening()
|
|
110
|
+
this.socket = undefined
|
|
111
|
+
const gracefulLeave = (code === GOING_AWAY) || (code === CUSTOM_GOING_AWAY)
|
|
112
|
+
this.emit('disconnected', gracefulLeave, code, reason)
|
|
113
|
+
this.removeAllListeners()
|
|
114
|
+
}
|
|
115
|
+
|
|
129
116
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Logger } from '@streamr/utils'
|
|
2
|
+
import { ICloseEvent, IMessageEvent, w3cwebsocket as Websocket } from 'websocket'
|
|
3
|
+
import { AbstractWebsocketClientConnection } from './AbstractWebsocketClientConnection'
|
|
4
|
+
|
|
5
|
+
const logger = new Logger(module)
|
|
6
|
+
|
|
7
|
+
const BINARY_TYPE = 'arraybuffer'
|
|
8
|
+
|
|
9
|
+
export class WebsocketClientConnection extends AbstractWebsocketClientConnection {
|
|
10
|
+
|
|
11
|
+
protected socket?: Websocket
|
|
12
|
+
|
|
13
|
+
// TODO explicit default value for "selfSigned" or make it required
|
|
14
|
+
public connect(address: string, selfSigned?: boolean): void {
|
|
15
|
+
if (!this.destroyed) {
|
|
16
|
+
this.socket = new Websocket(address, undefined, undefined, undefined, { rejectUnauthorized: !selfSigned })
|
|
17
|
+
this.socket.binaryType = BINARY_TYPE
|
|
18
|
+
this.socket.onerror = (error: Error) => this.onError(error)
|
|
19
|
+
this.socket.onopen = () => this.onOpen()
|
|
20
|
+
this.socket.onclose = (event: ICloseEvent) => this.onClose(event.code, event.reason)
|
|
21
|
+
this.socket.onmessage = (message: IMessageEvent) => {
|
|
22
|
+
if (!this.destroyed) {
|
|
23
|
+
if (typeof message.data === 'string') {
|
|
24
|
+
logger.debug('Received string data, only binary data is supported')
|
|
25
|
+
} else {
|
|
26
|
+
this.onMessage(new Uint8Array(message.data))
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
} else {
|
|
31
|
+
logger.debug('Tried to connect() a stopped connection')
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
protected stopListening(): void {
|
|
36
|
+
if (this.socket) {
|
|
37
|
+
this.socket.onopen = undefined as unknown as (() => void)
|
|
38
|
+
this.socket.onclose = undefined as unknown as (() => void)
|
|
39
|
+
this.socket.onerror = undefined as unknown as (() => void)
|
|
40
|
+
this.socket.onmessage = undefined as unknown as (() => void)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Logger, binaryToUtf8 } from '@streamr/utils'
|
|
2
|
+
import { WebSocket } from 'ws'
|
|
3
|
+
import { AbstractWebsocketClientConnection } from './AbstractWebsocketClientConnection'
|
|
4
|
+
|
|
5
|
+
const logger = new Logger(module)
|
|
6
|
+
|
|
7
|
+
const BINARY_TYPE = 'nodebuffer'
|
|
8
|
+
|
|
9
|
+
export class WebsocketClientConnection extends AbstractWebsocketClientConnection {
|
|
10
|
+
|
|
11
|
+
protected socket?: WebSocket
|
|
12
|
+
|
|
13
|
+
// TODO explicit default value for "selfSigned" or make it required
|
|
14
|
+
public connect(address: string, selfSigned?: boolean): void {
|
|
15
|
+
if (!this.destroyed) {
|
|
16
|
+
this.socket = new WebSocket(address, { rejectUnauthorized: !selfSigned })
|
|
17
|
+
this.socket.binaryType = BINARY_TYPE
|
|
18
|
+
this.socket.on('error', (error: Error) => this.onError(error))
|
|
19
|
+
this.socket.on('open', () => this.onOpen())
|
|
20
|
+
this.socket.on('close', (code: number, reason: Buffer) => this.onClose(code, binaryToUtf8(reason)))
|
|
21
|
+
this.socket.on('message', (message: Buffer, isBinary: boolean) => {
|
|
22
|
+
if (!this.destroyed) {
|
|
23
|
+
if (isBinary === false) {
|
|
24
|
+
logger.debug('Received string data, only binary data is supported')
|
|
25
|
+
} else {
|
|
26
|
+
this.onMessage(new Uint8Array(message))
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
})
|
|
30
|
+
} else {
|
|
31
|
+
logger.debug('Tried to connect() a stopped connection')
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
protected stopListening(): void {
|
|
36
|
+
this.socket?.removeAllListeners()
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
}
|