@streamr/dht 100.0.0-pretestnet.6 → 100.0.0-testnet-one.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/connection/ConnectionLockHandler.js +2 -2
- package/dist/src/connection/ConnectionLockHandler.js.map +1 -1
- package/dist/src/connection/ConnectionLockRpcRemote.d.ts +2 -2
- package/dist/src/connection/ConnectionLockRpcRemote.js +3 -27
- package/dist/src/connection/ConnectionLockRpcRemote.js.map +1 -1
- package/dist/src/connection/ConnectionManager.d.ts +0 -1
- package/dist/src/connection/ConnectionManager.js +11 -7
- package/dist/src/connection/ConnectionManager.js.map +1 -1
- package/dist/src/connection/ConnectorFacade.d.ts +2 -2
- package/dist/src/connection/ConnectorFacade.js +1 -2
- package/dist/src/connection/ConnectorFacade.js.map +1 -1
- package/dist/src/connection/ManagedConnection.js +1 -0
- package/dist/src/connection/ManagedConnection.js.map +1 -1
- package/dist/src/connection/connectivityChecker.d.ts +9 -0
- package/dist/src/connection/connectivityChecker.js +122 -0
- package/dist/src/connection/connectivityChecker.js.map +1 -0
- package/dist/src/connection/connectivityRequestHandler.d.ts +2 -0
- package/dist/src/connection/connectivityRequestHandler.js +79 -0
- package/dist/src/connection/connectivityRequestHandler.js.map +1 -0
- package/dist/src/connection/simulator/Simulator.js +3 -2
- package/dist/src/connection/simulator/Simulator.js.map +1 -1
- package/dist/src/connection/simulator/SimulatorConnection.js +1 -1
- package/dist/src/connection/simulator/SimulatorConnection.js.map +1 -1
- package/dist/src/connection/webrtc/NodeWebrtcConnection.js +1 -1
- package/dist/src/connection/webrtc/NodeWebrtcConnection.js.map +1 -1
- package/dist/src/connection/webrtc/WebrtcConnector.js +1 -1
- package/dist/src/connection/webrtc/WebrtcConnector.js.map +1 -1
- package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.js +1 -1
- package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.js.map +1 -1
- package/dist/src/connection/webrtc/WebrtcConnectorRpcRemote.d.ts +2 -2
- package/dist/src/connection/webrtc/WebrtcConnectorRpcRemote.js +2 -2
- package/dist/src/connection/webrtc/WebrtcConnectorRpcRemote.js.map +1 -1
- package/dist/src/connection/webrtc/iceServerAsString.js +1 -1
- package/dist/src/connection/webrtc/iceServerAsString.js.map +1 -1
- package/dist/src/connection/websocket/ClientWebsocket.d.ts +1 -0
- package/dist/src/connection/websocket/ClientWebsocket.js +7 -3
- package/dist/src/connection/websocket/ClientWebsocket.js.map +1 -1
- package/dist/src/connection/websocket/ServerWebsocket.d.ts +4 -0
- package/dist/src/connection/websocket/ServerWebsocket.js +32 -21
- package/dist/src/connection/websocket/ServerWebsocket.js.map +1 -1
- package/dist/src/connection/websocket/WebsocketConnector.d.ts +0 -2
- package/dist/src/connection/websocket/WebsocketConnector.js +61 -16
- package/dist/src/connection/websocket/WebsocketConnector.js.map +1 -1
- package/dist/src/connection/websocket/WebsocketConnectorRpcLocal.d.ts +1 -1
- package/dist/src/connection/websocket/WebsocketConnectorRpcLocal.js +8 -11
- package/dist/src/connection/websocket/WebsocketConnectorRpcLocal.js.map +1 -1
- package/dist/src/connection/websocket/WebsocketConnectorRpcRemote.d.ts +4 -4
- package/dist/src/connection/websocket/WebsocketConnectorRpcRemote.js +5 -39
- package/dist/src/connection/websocket/WebsocketConnectorRpcRemote.js.map +1 -1
- package/dist/src/connection/websocket/WebsocketServer.js +21 -4
- package/dist/src/connection/websocket/WebsocketServer.js.map +1 -1
- package/dist/src/dht/DhtNode.d.ts +13 -23
- package/dist/src/dht/DhtNode.js +97 -226
- package/dist/src/dht/DhtNode.js.map +1 -1
- package/dist/src/dht/DhtNodeRpcLocal.d.ts +1 -4
- package/dist/src/dht/DhtNodeRpcLocal.js +1 -5
- package/dist/src/dht/DhtNodeRpcLocal.js.map +1 -1
- package/dist/src/dht/DhtNodeRpcRemote.d.ts +3 -3
- package/dist/src/dht/DhtNodeRpcRemote.js +4 -4
- package/dist/src/dht/DhtNodeRpcRemote.js.map +1 -1
- package/dist/src/dht/ExternalApiRpcLocal.d.ts +4 -4
- package/dist/src/dht/ExternalApiRpcLocal.js +5 -12
- package/dist/src/dht/ExternalApiRpcLocal.js.map +1 -1
- package/dist/src/dht/ExternalApiRpcRemote.d.ts +3 -3
- package/dist/src/dht/ExternalApiRpcRemote.js +5 -5
- package/dist/src/dht/ExternalApiRpcRemote.js.map +1 -1
- package/dist/src/dht/PeerManager.d.ts +52 -0
- package/dist/src/dht/PeerManager.js +273 -0
- package/dist/src/dht/PeerManager.js.map +1 -0
- package/dist/src/dht/contact/ContactList.d.ts +1 -1
- package/dist/src/dht/contact/ContactList.js +1 -0
- package/dist/src/dht/contact/ContactList.js.map +1 -1
- package/dist/src/dht/contact/{Remote.d.ts → RpcRemote.d.ts} +3 -3
- package/dist/src/dht/contact/{Remote.js → RpcRemote.js} +8 -8
- package/dist/src/dht/contact/RpcRemote.js.map +1 -0
- package/dist/src/dht/contact/SortedContactList.d.ts +20 -6
- package/dist/src/dht/contact/SortedContactList.js +55 -24
- package/dist/src/dht/contact/SortedContactList.js.map +1 -1
- package/dist/src/dht/discovery/DiscoverySession.d.ts +4 -14
- package/dist/src/dht/discovery/DiscoverySession.js +15 -26
- package/dist/src/dht/discovery/DiscoverySession.js.map +1 -1
- package/dist/src/dht/discovery/PeerDiscovery.d.ts +2 -9
- package/dist/src/dht/discovery/PeerDiscovery.js +11 -19
- package/dist/src/dht/discovery/PeerDiscovery.js.map +1 -1
- package/dist/src/dht/find/FindRpcLocal.js +2 -1
- package/dist/src/dht/find/FindRpcLocal.js.map +1 -1
- package/dist/src/dht/find/FindSession.d.ts +6 -6
- package/dist/src/dht/find/FindSession.js +18 -13
- package/dist/src/dht/find/FindSession.js.map +1 -1
- package/dist/src/dht/find/FindSessionRpcLocal.d.ts +1 -1
- package/dist/src/dht/find/FindSessionRpcRemote.d.ts +2 -2
- package/dist/src/dht/find/FindSessionRpcRemote.js +2 -2
- package/dist/src/dht/find/FindSessionRpcRemote.js.map +1 -1
- package/dist/src/dht/find/Finder.d.ts +4 -4
- package/dist/src/dht/find/Finder.js +55 -42
- package/dist/src/dht/find/Finder.js.map +1 -1
- package/dist/src/dht/routing/FindRpcRemote.d.ts +2 -2
- package/dist/src/dht/routing/FindRpcRemote.js +7 -5
- package/dist/src/dht/routing/FindRpcRemote.js.map +1 -1
- package/dist/src/dht/routing/Router.d.ts +3 -7
- package/dist/src/dht/routing/Router.js +29 -22
- package/dist/src/dht/routing/Router.js.map +1 -1
- package/dist/src/dht/routing/RouterRpcLocal.d.ts +2 -2
- package/dist/src/dht/routing/RouterRpcLocal.js +4 -3
- package/dist/src/dht/routing/RouterRpcLocal.js.map +1 -1
- package/dist/src/dht/routing/RouterRpcRemote.d.ts +2 -2
- package/dist/src/dht/routing/RouterRpcRemote.js +13 -8
- package/dist/src/dht/routing/RouterRpcRemote.js.map +1 -1
- package/dist/src/dht/routing/RoutingSession.d.ts +1 -1
- package/dist/src/dht/routing/RoutingSession.js +23 -11
- package/dist/src/dht/routing/RoutingSession.js.map +1 -1
- package/dist/src/dht/routing/getPreviousPeer.js.map +1 -1
- package/dist/src/dht/store/LocalDataStore.d.ts +3 -3
- package/dist/src/dht/store/LocalDataStore.js +18 -17
- package/dist/src/dht/store/LocalDataStore.js.map +1 -1
- package/dist/src/dht/store/StoreRpcLocal.d.ts +10 -9
- package/dist/src/dht/store/StoreRpcLocal.js +108 -102
- package/dist/src/dht/store/StoreRpcLocal.js.map +1 -1
- package/dist/src/dht/store/StoreRpcRemote.d.ts +4 -5
- package/dist/src/dht/store/StoreRpcRemote.js +6 -15
- package/dist/src/dht/store/StoreRpcRemote.js.map +1 -1
- package/dist/src/exports.d.ts +1 -1
- package/dist/src/exports.js +4 -4
- package/dist/src/exports.js.map +1 -1
- package/dist/src/helpers/PeerID.d.ts +1 -0
- package/dist/src/helpers/PeerID.js +9 -4
- package/dist/src/helpers/PeerID.js.map +1 -1
- package/dist/src/helpers/UUID.js +1 -1
- package/dist/src/helpers/UUID.js.map +1 -1
- package/dist/src/helpers/nodeId.d.ts +1 -0
- package/dist/src/helpers/{kademliaId.js → nodeId.js} +4 -4
- package/dist/src/helpers/nodeId.js.map +1 -0
- package/dist/src/helpers/peerIdFromPeerDescriptor.js +4 -4
- package/dist/src/helpers/peerIdFromPeerDescriptor.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.d.ts +5 -16
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.js +2 -9
- package/dist/src/proto/packages/dht/protos/DhtRpc.client.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.d.ts +80 -95
- package/dist/src/proto/packages/dht/protos/DhtRpc.js +67 -66
- package/dist/src/proto/packages/dht/protos/DhtRpc.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.server.d.ts +3 -10
- package/dist/src/transport/RoutingRpcCommunicator.js +2 -0
- package/dist/src/transport/RoutingRpcCommunicator.js.map +1 -1
- package/karma.config.js +2 -2
- package/package.json +5 -5
- package/protos/DhtRpc.proto +36 -36
- package/src/connection/ConnectionLockHandler.ts +2 -2
- package/src/connection/ConnectionLockRpcRemote.ts +3 -4
- package/src/connection/ConnectionManager.ts +19 -17
- package/src/connection/ConnectorFacade.ts +5 -7
- package/src/connection/ManagedConnection.ts +1 -0
- package/src/connection/connectivityChecker.ts +102 -0
- package/src/connection/connectivityRequestHandler.ts +79 -0
- package/src/connection/simulator/Simulator.ts +3 -2
- package/src/connection/simulator/SimulatorConnection.ts +1 -1
- package/src/connection/webrtc/BrowserWebrtcConnection.ts +10 -10
- package/src/connection/webrtc/NodeWebrtcConnection.ts +1 -1
- package/src/connection/webrtc/WebrtcConnector.ts +1 -1
- package/src/connection/webrtc/WebrtcConnectorRpcLocal.ts +1 -1
- package/src/connection/webrtc/WebrtcConnectorRpcRemote.ts +2 -2
- package/src/connection/webrtc/iceServerAsString.ts +1 -1
- package/src/connection/websocket/ClientWebsocket.ts +6 -2
- package/src/connection/websocket/ServerWebsocket.ts +40 -25
- package/src/connection/websocket/WebsocketConnector.ts +43 -22
- package/src/connection/websocket/WebsocketConnectorRpcLocal.ts +9 -11
- package/src/connection/websocket/WebsocketConnectorRpcRemote.ts +7 -16
- package/src/connection/websocket/WebsocketServer.ts +20 -5
- package/src/dht/DhtNode.ts +123 -280
- package/src/dht/DhtNodeRpcLocal.ts +2 -9
- package/src/dht/DhtNodeRpcRemote.ts +4 -4
- package/src/dht/ExternalApiRpcLocal.ts +8 -13
- package/src/dht/ExternalApiRpcRemote.ts +5 -5
- package/src/dht/PeerManager.ts +330 -0
- package/src/dht/contact/ContactList.ts +3 -2
- package/src/dht/contact/{Remote.ts → RpcRemote.ts} +7 -6
- package/src/dht/contact/SortedContactList.ts +87 -44
- package/src/dht/discovery/DiscoverySession.ts +19 -44
- package/src/dht/discovery/PeerDiscovery.ts +16 -28
- package/src/dht/find/FindRpcLocal.ts +2 -2
- package/src/dht/find/FindSession.ts +25 -20
- package/src/dht/find/FindSessionRpcLocal.ts +1 -1
- package/src/dht/find/FindSessionRpcRemote.ts +2 -2
- package/src/dht/find/Finder.ts +84 -64
- package/src/dht/routing/FindRpcRemote.ts +7 -5
- package/src/dht/routing/Router.ts +30 -25
- package/src/dht/routing/RouterRpcLocal.ts +5 -5
- package/src/dht/routing/RouterRpcRemote.ts +13 -10
- package/src/dht/routing/RoutingSession.ts +22 -17
- package/src/dht/routing/getPreviousPeer.ts +1 -1
- package/src/dht/store/LocalDataStore.ts +18 -17
- package/src/dht/store/StoreRpcLocal.ts +118 -113
- package/src/dht/store/StoreRpcRemote.ts +7 -23
- package/src/exports.ts +1 -1
- package/src/helpers/PeerID.ts +8 -4
- package/src/helpers/UUID.ts +1 -1
- package/src/helpers/{kademliaId.ts → nodeId.ts} +1 -1
- package/src/helpers/peerIdFromPeerDescriptor.ts +6 -6
- package/src/proto/packages/dht/protos/DhtRpc.client.ts +6 -20
- package/src/proto/packages/dht/protos/DhtRpc.server.ts +3 -10
- package/src/proto/packages/dht/protos/DhtRpc.ts +103 -135
- package/src/transport/RoutingRpcCommunicator.ts +2 -0
- package/test/benchmark/Find.test.ts +5 -5
- package/test/benchmark/KademliaCorrectness.test.ts +3 -3
- package/test/benchmark/SortedContactListBenchmark.test.ts +150 -0
- package/test/benchmark/WebsocketServerMemoryLeak.test.ts +41 -0
- package/test/benchmark/kademlia-simulation/Contact.ts +1 -1
- package/test/benchmark/kademlia-simulation/KademliaSimulation.ts +1 -1
- package/test/benchmark/kademlia-simulation/SimulationNode.ts +6 -1
- package/test/end-to-end/Layer0-Layer1.test.ts +1 -1
- package/test/end-to-end/Layer0.test.ts +4 -4
- package/test/end-to-end/Layer0MixedConnectionTypes.test.ts +11 -11
- package/test/end-to-end/Layer0Webrtc-Layer1.test.ts +6 -6
- package/test/end-to-end/Layer0Webrtc.test.ts +2 -2
- package/test/end-to-end/Layer1-Scale-WebSocket.test.ts +3 -3
- package/test/end-to-end/Layer1-Scale-Webrtc.test.ts +3 -3
- package/test/end-to-end/RecoveryFromFailedAutoCertification.test.ts +1 -1
- package/test/end-to-end/WebsocketConnectionRequest.test.ts +1 -1
- package/test/end-to-end/memory-leak.test.ts +9 -12
- package/test/integration/ConnectionLocking.test.ts +2 -2
- package/test/integration/ConnectionManager.test.ts +14 -14
- package/test/integration/DhtJoinPeerDiscovery.test.ts +3 -3
- package/test/integration/DhtNodeExternalAPI.test.ts +10 -7
- package/test/integration/DhtNodeRpcRemote.test.ts +4 -4
- package/test/integration/DhtRpc.test.ts +6 -6
- package/test/integration/Find.test.ts +3 -3
- package/test/integration/Layer1-scale.test.ts +3 -3
- package/test/integration/Mock-Layer1-Layer0.test.ts +16 -16
- package/test/integration/MultipleEntryPointJoining.test.ts +7 -7
- package/test/integration/{MigrateData.test.ts → ReplicateData.test.ts} +15 -10
- package/test/integration/RouteMessage.test.ts +2 -2
- package/test/integration/RouterRpcRemote.test.ts +2 -2
- package/test/integration/RpcErrors.test.ts +2 -2
- package/test/integration/ScaleDownDht.test.ts +4 -2
- package/test/integration/SimultaneousConnections.test.ts +89 -57
- package/test/integration/Store.test.ts +33 -13
- package/test/integration/StoreAndDelete.test.ts +19 -17
- package/test/integration/StoreOnDhtWithTwoNodes.test.ts +21 -21
- package/test/integration/StoreRpcRemote.test.ts +3 -3
- package/test/integration/WebrtcConnectionManagement.test.ts +2 -2
- package/test/integration/WebrtcConnectorRpc.test.ts +1 -1
- package/test/integration/WebsocketConnectionManagement.test.ts +41 -3
- package/test/integration/WebsocketConnectorRpc.test.ts +5 -7
- package/test/unit/ConnectivityHelpers.test.ts +4 -4
- package/test/unit/Finder.test.ts +69 -23
- package/test/unit/LocalDataStore.test.ts +60 -43
- package/test/unit/RandomContactList.test.ts +2 -2
- package/test/unit/Router.test.ts +19 -11
- package/test/unit/RoutingSession.test.ts +76 -0
- package/test/unit/SortedContactList.test.ts +17 -12
- package/test/unit/WebsocketConnector.test.ts +1 -1
- package/test/unit/connectivityRequestHandler.test.ts +71 -0
- package/test/utils/mock/Router.ts +1 -1
- package/test/utils/utils.ts +24 -22
- package/dist/src/connection/ConnectivityChecker.d.ts +0 -17
- package/dist/src/connection/ConnectivityChecker.js +0 -208
- package/dist/src/connection/ConnectivityChecker.js.map +0 -1
- package/dist/src/dht/contact/Remote.js.map +0 -1
- package/dist/src/helpers/kademliaId.d.ts +0 -1
- package/dist/src/helpers/kademliaId.js.map +0 -1
- package/src/connection/ConnectivityChecker.ts +0 -199
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { Logger, RunAndRaceEventsReturnType, runAndRaceEvents3 } from '@streamr/utils'
|
|
2
|
+
import { v4 } from 'uuid'
|
|
3
|
+
import * as Err from '../helpers/errors'
|
|
4
|
+
import {
|
|
5
|
+
ConnectivityRequest, ConnectivityResponse,
|
|
6
|
+
Message, MessageType, PeerDescriptor
|
|
7
|
+
} from '../proto/packages/dht/protos/DhtRpc'
|
|
8
|
+
import { ConnectionEvents, IConnection } from './IConnection'
|
|
9
|
+
import { ClientWebsocket } from './websocket/ClientWebsocket'
|
|
10
|
+
import { connectivityMethodToWebsocketUrl } from './websocket/WebsocketConnector'
|
|
11
|
+
|
|
12
|
+
const logger = new Logger(module)
|
|
13
|
+
|
|
14
|
+
export const connectAsync = async ({ url, selfSigned, timeoutMs = 1000 }:
|
|
15
|
+
{ url: string, selfSigned: boolean, timeoutMs?: number }
|
|
16
|
+
): Promise<IConnection> => {
|
|
17
|
+
const socket = new ClientWebsocket()
|
|
18
|
+
let result: RunAndRaceEventsReturnType<ConnectionEvents>
|
|
19
|
+
try {
|
|
20
|
+
result = await runAndRaceEvents3<ConnectionEvents>([
|
|
21
|
+
() => { socket.connect(url, selfSigned) }],
|
|
22
|
+
socket, ['connected', 'error'],
|
|
23
|
+
timeoutMs)
|
|
24
|
+
} catch (e) {
|
|
25
|
+
throw new Err.ConnectionFailed('WebSocket connection timed out')
|
|
26
|
+
}
|
|
27
|
+
if (result.winnerName === 'error') {
|
|
28
|
+
throw new Err.ConnectionFailed('Could not open WebSocket connection')
|
|
29
|
+
}
|
|
30
|
+
return socket
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export const CONNECTIVITY_CHECKER_SERVICE_ID = 'system/connectivity-checker'
|
|
34
|
+
const CONNECTIVITY_CHECKER_TIMEOUT = 5000
|
|
35
|
+
|
|
36
|
+
export const sendConnectivityRequest = async (
|
|
37
|
+
request: ConnectivityRequest,
|
|
38
|
+
entryPoint: PeerDescriptor
|
|
39
|
+
): Promise<ConnectivityResponse> => {
|
|
40
|
+
let outgoingConnection: IConnection
|
|
41
|
+
const wsServerInfo = {
|
|
42
|
+
host: entryPoint.websocket!.host,
|
|
43
|
+
port: entryPoint.websocket!.port,
|
|
44
|
+
tls: entryPoint.websocket!.tls,
|
|
45
|
+
}
|
|
46
|
+
const url = connectivityMethodToWebsocketUrl(wsServerInfo, 'connectivityRequest')
|
|
47
|
+
logger.debug(`Attempting connectivity check with entrypoint ${url}`)
|
|
48
|
+
try {
|
|
49
|
+
outgoingConnection = await connectAsync({
|
|
50
|
+
url,
|
|
51
|
+
selfSigned: request.selfSigned
|
|
52
|
+
})
|
|
53
|
+
} catch (e) {
|
|
54
|
+
throw new Err.ConnectionFailed(`Failed to connect to entrypoint for connectivity check: ${url}`, e)
|
|
55
|
+
}
|
|
56
|
+
// send connectivity request
|
|
57
|
+
const msg: Message = {
|
|
58
|
+
serviceId: CONNECTIVITY_CHECKER_SERVICE_ID,
|
|
59
|
+
messageType: MessageType.CONNECTIVITY_REQUEST, messageId: v4(),
|
|
60
|
+
body: {
|
|
61
|
+
oneofKind: 'connectivityRequest',
|
|
62
|
+
connectivityRequest: request
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const responseAwaiter = () => {
|
|
66
|
+
return new Promise((resolve: (res: ConnectivityResponse) => void, reject) => {
|
|
67
|
+
const timeoutId = setTimeout(() => {
|
|
68
|
+
// TODO should we have some handling for this floating promise?
|
|
69
|
+
outgoingConnection.close(false)
|
|
70
|
+
reject(new Err.ConnectivityResponseTimeout('timeout'))
|
|
71
|
+
}, CONNECTIVITY_CHECKER_TIMEOUT)
|
|
72
|
+
const listener = (bytes: Uint8Array) => {
|
|
73
|
+
// TODO should we have some handling for this floating promise?
|
|
74
|
+
outgoingConnection.close(false)
|
|
75
|
+
try {
|
|
76
|
+
const message: Message = Message.fromBinary(bytes)
|
|
77
|
+
if (message.body.oneofKind === 'connectivityResponse') {
|
|
78
|
+
logger.debug('ConnectivityResponse received: ' + JSON.stringify(Message.toJson(message)))
|
|
79
|
+
const connectivityResponseMessage = message.body.connectivityResponse
|
|
80
|
+
outgoingConnection!.off('data', listener)
|
|
81
|
+
clearTimeout(timeoutId)
|
|
82
|
+
resolve(connectivityResponseMessage)
|
|
83
|
+
} else {
|
|
84
|
+
return
|
|
85
|
+
}
|
|
86
|
+
} catch (err) {
|
|
87
|
+
logger.trace(`Could not parse message: ${err}`)
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
outgoingConnection!.on('data', listener)
|
|
91
|
+
})
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
const retPromise = responseAwaiter()
|
|
95
|
+
outgoingConnection.send(Message.toBinary(msg))
|
|
96
|
+
logger.trace('ConnectivityRequest sent: ' + JSON.stringify(Message.toJson(msg)))
|
|
97
|
+
return await retPromise
|
|
98
|
+
} catch (e) {
|
|
99
|
+
logger.error('error getting connectivityresponse')
|
|
100
|
+
throw e
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { Logger } from '@streamr/utils'
|
|
2
|
+
import { v4 } from 'uuid'
|
|
3
|
+
import {
|
|
4
|
+
ConnectivityRequest, ConnectivityResponse,
|
|
5
|
+
Message, MessageType
|
|
6
|
+
} from '../proto/packages/dht/protos/DhtRpc'
|
|
7
|
+
import { NatType } from './ConnectionManager'
|
|
8
|
+
import { CONNECTIVITY_CHECKER_SERVICE_ID, connectAsync } from './connectivityChecker'
|
|
9
|
+
import { IConnection } from './IConnection'
|
|
10
|
+
import { ServerWebsocket } from './websocket/ServerWebsocket'
|
|
11
|
+
import { connectivityMethodToWebsocketUrl } from './websocket/WebsocketConnector'
|
|
12
|
+
|
|
13
|
+
const logger = new Logger(module)
|
|
14
|
+
|
|
15
|
+
export const attachConnectivityRequestHandler = (connectionToListenTo: ServerWebsocket): void => {
|
|
16
|
+
connectionToListenTo.on('data', async (data: Uint8Array) => {
|
|
17
|
+
logger.trace('server received data')
|
|
18
|
+
try {
|
|
19
|
+
const message = Message.fromBinary(data)
|
|
20
|
+
if (message.body.oneofKind === 'connectivityRequest') {
|
|
21
|
+
logger.trace('ConnectivityRequest received: ' + JSON.stringify(Message.toJson(message)))
|
|
22
|
+
try {
|
|
23
|
+
await handleIncomingConnectivityRequest(connectionToListenTo, message.body.connectivityRequest)
|
|
24
|
+
logger.trace('handleIncomingConnectivityRequest ok')
|
|
25
|
+
} catch (e) {
|
|
26
|
+
logger.error('handleIncomingConnectivityRequest', { error: e })
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
} catch (err) {
|
|
30
|
+
logger.trace(`Could not parse message: ${err}`)
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const handleIncomingConnectivityRequest = async (connection: ServerWebsocket, connectivityRequest: ConnectivityRequest): Promise<void> => {
|
|
36
|
+
let outgoingConnection: IConnection | undefined
|
|
37
|
+
let connectivityResponseMessage: ConnectivityResponse | undefined
|
|
38
|
+
const host = connectivityRequest.host ?? connection.getRemoteAddress()
|
|
39
|
+
try {
|
|
40
|
+
const wsServerInfo = {
|
|
41
|
+
host,
|
|
42
|
+
port: connectivityRequest.port,
|
|
43
|
+
tls: connectivityRequest.tls
|
|
44
|
+
}
|
|
45
|
+
const url = connectivityMethodToWebsocketUrl(wsServerInfo, 'connectivityProbe')
|
|
46
|
+
logger.trace(`Attempting Connectivity Check to ${url}`)
|
|
47
|
+
outgoingConnection = await connectAsync({
|
|
48
|
+
url,
|
|
49
|
+
selfSigned: connectivityRequest.selfSigned
|
|
50
|
+
})
|
|
51
|
+
} catch (err) {
|
|
52
|
+
logger.debug('error', { err })
|
|
53
|
+
connectivityResponseMessage = {
|
|
54
|
+
host,
|
|
55
|
+
natType: NatType.UNKNOWN
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (outgoingConnection) {
|
|
59
|
+
// TODO should we have some handling for this floating promise?
|
|
60
|
+
outgoingConnection.close(false)
|
|
61
|
+
logger.trace('Connectivity test produced positive result, communicating reply to the requester ' + host + ':' + connectivityRequest.port)
|
|
62
|
+
connectivityResponseMessage = {
|
|
63
|
+
host,
|
|
64
|
+
natType: NatType.OPEN_INTERNET,
|
|
65
|
+
websocket: { host, port: connectivityRequest.port, tls: connectivityRequest.tls }
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const msg: Message = {
|
|
69
|
+
serviceId: CONNECTIVITY_CHECKER_SERVICE_ID,
|
|
70
|
+
messageType: MessageType.CONNECTIVITY_RESPONSE,
|
|
71
|
+
messageId: v4(),
|
|
72
|
+
body: {
|
|
73
|
+
oneofKind: 'connectivityResponse',
|
|
74
|
+
connectivityResponse: connectivityResponseMessage!
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
connection.send(Message.toBinary(msg))
|
|
78
|
+
logger.trace('ConnectivityResponse sent: ' + JSON.stringify(Message.toJson(msg)))
|
|
79
|
+
}
|
|
@@ -148,7 +148,7 @@ export class Simulator extends EventEmitter<ConnectionSourceEvents> {
|
|
|
148
148
|
this.latencyTable = getRegionDelayMatrix()
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
-
if (this.latencyType === LatencyType.FIXED &&
|
|
151
|
+
if ((this.latencyType === LatencyType.FIXED) && (this.fixedLatency === undefined)) {
|
|
152
152
|
throw new Error('LatencyType.FIXED requires the desired latency to be given as second parameter')
|
|
153
153
|
}
|
|
154
154
|
|
|
@@ -185,7 +185,7 @@ export class Simulator extends EventEmitter<ConnectionSourceEvents> {
|
|
|
185
185
|
|
|
186
186
|
if (sourceRegion === undefined || targetRegion === undefined || sourceRegion > 15 || targetRegion > 15) {
|
|
187
187
|
logger.error('invalid region index given to Simulator')
|
|
188
|
-
throw ('invalid region index given to Simulator')
|
|
188
|
+
throw new Error('invalid region index given to Simulator')
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
latency = this.latencyTable![sourceRegion][targetRegion]
|
|
@@ -313,6 +313,7 @@ export class Simulator extends EventEmitter<ConnectionSourceEvents> {
|
|
|
313
313
|
this.simulatorTimeout = setTimeout(this.executeQueuedOperations, timeDifference)
|
|
314
314
|
|
|
315
315
|
if (Simulator.clock) {
|
|
316
|
+
// TODO should we have some handling for this floating promise?
|
|
316
317
|
Simulator.clock.runAllAsync()
|
|
317
318
|
}
|
|
318
319
|
}
|
|
@@ -85,7 +85,7 @@ export class SimulatorConnection extends Connection implements IConnection {
|
|
|
85
85
|
logger.trace('connect() called')
|
|
86
86
|
|
|
87
87
|
this.simulator.connect(this, this.targetPeerDescriptor, (error?: string) => {
|
|
88
|
-
if (error) {
|
|
88
|
+
if (error !== undefined) {
|
|
89
89
|
logger.trace(error)
|
|
90
90
|
this.doDisconnect(false)
|
|
91
91
|
} else {
|
|
@@ -51,7 +51,7 @@ export class NodeWebrtcConnection extends EventEmitter<Events> implements IWebrt
|
|
|
51
51
|
this.peerConnection = new RTCPeerConnection({ iceServers: urls })
|
|
52
52
|
|
|
53
53
|
this.peerConnection.onicecandidate = (event) => {
|
|
54
|
-
if (event.candidate && event.candidate.sdpMid) {
|
|
54
|
+
if ((event.candidate !== null) && (event.candidate.sdpMid !== null)) {
|
|
55
55
|
this.emit('localCandidate', event.candidate.candidate, event.candidate.sdpMid)
|
|
56
56
|
}
|
|
57
57
|
}
|
|
@@ -63,14 +63,14 @@ export class NodeWebrtcConnection extends EventEmitter<Events> implements IWebrt
|
|
|
63
63
|
if (isOffering) {
|
|
64
64
|
this.peerConnection.onnegotiationneeded = async () => {
|
|
65
65
|
try {
|
|
66
|
-
if (this.peerConnection) {
|
|
66
|
+
if (this.peerConnection !== undefined) {
|
|
67
67
|
this.makingOffer = true
|
|
68
68
|
try {
|
|
69
69
|
await this.peerConnection.setLocalDescription()
|
|
70
70
|
} catch (err) {
|
|
71
71
|
logger.warn('error', { err })
|
|
72
72
|
}
|
|
73
|
-
if (this.peerConnection.localDescription) {
|
|
73
|
+
if (this.peerConnection.localDescription !== null) {
|
|
74
74
|
this.emit('localDescription', this.peerConnection.localDescription?.sdp, this.peerConnection.localDescription?.type)
|
|
75
75
|
}
|
|
76
76
|
}
|
|
@@ -93,7 +93,7 @@ export class NodeWebrtcConnection extends EventEmitter<Events> implements IWebrt
|
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
public async setRemoteDescription(description: string, type: string): Promise<void> {
|
|
96
|
-
const offerCollision = (type.toLowerCase() === RtcDescription.OFFER) && (this.makingOffer ||
|
|
96
|
+
const offerCollision = (type.toLowerCase() === RtcDescription.OFFER) && (this.makingOffer || (this.peerConnection === undefined) ||
|
|
97
97
|
this.peerConnection.signalingState != 'stable')
|
|
98
98
|
|
|
99
99
|
const ignoreOffer = this.isOffering && offerCollision
|
|
@@ -106,13 +106,13 @@ export class NodeWebrtcConnection extends EventEmitter<Events> implements IWebrt
|
|
|
106
106
|
logger.warn('error', { err })
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
if (type.toLowerCase() === RtcDescription.OFFER && this.peerConnection) {
|
|
109
|
+
if ((type.toLowerCase() === RtcDescription.OFFER) && (this.peerConnection !== undefined)) {
|
|
110
110
|
try {
|
|
111
111
|
await this.peerConnection.setLocalDescription()
|
|
112
112
|
} catch (err) {
|
|
113
113
|
logger.warn('error', { err })
|
|
114
114
|
}
|
|
115
|
-
if (this.peerConnection.localDescription) {
|
|
115
|
+
if (this.peerConnection.localDescription !== null) {
|
|
116
116
|
this.emit('localDescription', this.peerConnection.localDescription.sdp, this.peerConnection.localDescription.type)
|
|
117
117
|
}
|
|
118
118
|
}
|
|
@@ -148,7 +148,7 @@ export class NodeWebrtcConnection extends EventEmitter<Events> implements IWebrt
|
|
|
148
148
|
|
|
149
149
|
this.removeAllListeners()
|
|
150
150
|
|
|
151
|
-
if (this.dataChannel) {
|
|
151
|
+
if (this.dataChannel !== undefined) {
|
|
152
152
|
try {
|
|
153
153
|
this.dataChannel.close()
|
|
154
154
|
} catch (e) {
|
|
@@ -158,7 +158,7 @@ export class NodeWebrtcConnection extends EventEmitter<Events> implements IWebrt
|
|
|
158
158
|
|
|
159
159
|
this.dataChannel = undefined
|
|
160
160
|
|
|
161
|
-
if (this.peerConnection) {
|
|
161
|
+
if (this.peerConnection !== undefined) {
|
|
162
162
|
try {
|
|
163
163
|
this.peerConnection.close()
|
|
164
164
|
} catch (e) {
|
|
@@ -209,7 +209,7 @@ export class NodeWebrtcConnection extends EventEmitter<Events> implements IWebrt
|
|
|
209
209
|
}
|
|
210
210
|
|
|
211
211
|
private stopListening() {
|
|
212
|
-
if (this.dataChannel) {
|
|
212
|
+
if (this.dataChannel !== undefined) {
|
|
213
213
|
this.dataChannel.onopen = null
|
|
214
214
|
this.dataChannel.onclose = null
|
|
215
215
|
this.dataChannel.onerror = null
|
|
@@ -217,7 +217,7 @@ export class NodeWebrtcConnection extends EventEmitter<Events> implements IWebrt
|
|
|
217
217
|
this.dataChannel.onmessage = null
|
|
218
218
|
}
|
|
219
219
|
|
|
220
|
-
if (this.peerConnection) {
|
|
220
|
+
if (this.peerConnection !== undefined) {
|
|
221
221
|
this.peerConnection.onicecandidate = null
|
|
222
222
|
this.peerConnection.onicegatheringstatechange = null
|
|
223
223
|
this.peerConnection.onnegotiationneeded = null
|
|
@@ -161,7 +161,7 @@ export class NodeWebrtcConnection extends EventEmitter<Events> implements IConne
|
|
|
161
161
|
if (!this.closed) {
|
|
162
162
|
logger.trace(
|
|
163
163
|
`Closing Node WebRTC Connection to ${getNodeIdFromPeerDescriptor(this.remotePeerDescriptor)}`
|
|
164
|
-
+ `${reason ? `, reason: ${reason}` : ''}`
|
|
164
|
+
+ `${(reason !== undefined) ? `, reason: ${reason}` : ''}`
|
|
165
165
|
)
|
|
166
166
|
|
|
167
167
|
this.closed = true
|
|
@@ -178,7 +178,7 @@ export class WebrtcConnector {
|
|
|
178
178
|
)
|
|
179
179
|
|
|
180
180
|
connection.on('localCandidate', (candidate: string, mid: string) => {
|
|
181
|
-
if (this.config.externalIp) {
|
|
181
|
+
if (this.config.externalIp !== undefined) {
|
|
182
182
|
candidate = replaceInternalIpWithExternalIp(candidate, this.config.externalIp)
|
|
183
183
|
logger.debug(`onLocalCandidate injected external ip ${candidate} ${mid}`)
|
|
184
184
|
}
|
|
@@ -123,7 +123,7 @@ export class WebrtcConnectorRpcLocal implements IWebrtcConnectorRpc {
|
|
|
123
123
|
private isIceCandidateAllowed(candidate: string): boolean {
|
|
124
124
|
if (!this.config.allowPrivateAddresses) {
|
|
125
125
|
const address = getAddressFromIceCandidate(candidate)
|
|
126
|
-
if (address && isPrivateIPv4(address)) {
|
|
126
|
+
if ((address !== undefined) && isPrivateIPv4(address)) {
|
|
127
127
|
return false
|
|
128
128
|
}
|
|
129
129
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RpcRemote } from '../../dht/contact/RpcRemote'
|
|
2
2
|
import {
|
|
3
3
|
IceCandidate,
|
|
4
4
|
PeerDescriptor,
|
|
@@ -12,7 +12,7 @@ import { Logger } from '@streamr/utils'
|
|
|
12
12
|
|
|
13
13
|
const logger = new Logger(module)
|
|
14
14
|
|
|
15
|
-
export class WebrtcConnectorRpcRemote extends
|
|
15
|
+
export class WebrtcConnectorRpcRemote extends RpcRemote<IWebrtcConnectorRpcClient> {
|
|
16
16
|
|
|
17
17
|
constructor(
|
|
18
18
|
localPeerDescriptor: PeerDescriptor,
|
|
@@ -9,7 +9,7 @@ export function iceServerAsString({ url, port, username, password, tcp }: IceSer
|
|
|
9
9
|
return `${protocol}:${hostname}:${port}`
|
|
10
10
|
}
|
|
11
11
|
if (username !== undefined && password !== undefined) {
|
|
12
|
-
return `${protocol}:${username}:${password}@${hostname}:${port}${tcp ? '?transport=tcp' : ''}`
|
|
12
|
+
return `${protocol}:${username}:${password}@${hostname}:${port}${(tcp !== undefined) ? '?transport=tcp' : ''}`
|
|
13
13
|
}
|
|
14
14
|
throw new Error(`username (${username}) and password (${password}) must be supplied together`)
|
|
15
15
|
}
|
|
@@ -8,6 +8,9 @@ const logger = new Logger(module)
|
|
|
8
8
|
// https://kapeli.com/cheat_sheets/WebSocket_Status_Codes.docset/Contents/Resources/Documents/index
|
|
9
9
|
// Browsers send this automatically when closing a tab
|
|
10
10
|
export const GOING_AWAY = 1001
|
|
11
|
+
// The GOING_AWAY is a reserved code and we shouldn't send that from the application. Therefore
|
|
12
|
+
// we have a custom counterpart
|
|
13
|
+
export const CUSTOM_GOING_AWAY = 3001
|
|
11
14
|
|
|
12
15
|
const BINARY_TYPE = 'arraybuffer'
|
|
13
16
|
|
|
@@ -23,6 +26,7 @@ export class ClientWebsocket extends EventEmitter<ConnectionEvents> implements I
|
|
|
23
26
|
this.connectionId = new ConnectionID()
|
|
24
27
|
}
|
|
25
28
|
|
|
29
|
+
// TODO explicit default value for "selfSigned" or make it required
|
|
26
30
|
public connect(address: string, selfSigned?: boolean): void {
|
|
27
31
|
if (!this.destroyed) {
|
|
28
32
|
this.socket = new Websocket(address, undefined, undefined, undefined, { rejectUnauthorized: !selfSigned })
|
|
@@ -68,7 +72,7 @@ export class ClientWebsocket extends EventEmitter<ConnectionEvents> implements I
|
|
|
68
72
|
this.destroyed = true
|
|
69
73
|
this.stopListening()
|
|
70
74
|
this.socket = undefined
|
|
71
|
-
const gracefulLeave = code === GOING_AWAY
|
|
75
|
+
const gracefulLeave = (code === GOING_AWAY) || (code === CUSTOM_GOING_AWAY)
|
|
72
76
|
this.emit('disconnected', gracefulLeave, code, reason)
|
|
73
77
|
this.removeAllListeners()
|
|
74
78
|
}
|
|
@@ -91,7 +95,7 @@ export class ClientWebsocket extends EventEmitter<ConnectionEvents> implements I
|
|
|
91
95
|
this.removeAllListeners()
|
|
92
96
|
if (!this.destroyed) {
|
|
93
97
|
logger.trace(`Closing socket for connection ${this.connectionId.toString()}`)
|
|
94
|
-
this.socket?.close(gracefulLeave
|
|
98
|
+
this.socket?.close(gracefulLeave ? CUSTOM_GOING_AWAY : undefined)
|
|
95
99
|
} else {
|
|
96
100
|
logger.debug('Tried to close() a stopped connection')
|
|
97
101
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import EventEmitter from 'eventemitter3'
|
|
2
2
|
import { IConnection, ConnectionID, ConnectionEvents, ConnectionType } from '../IConnection'
|
|
3
|
-
import { connection as WsConnection } from 'websocket'
|
|
3
|
+
import { Message, connection as WsConnection } from 'websocket'
|
|
4
4
|
import { Logger } from '@streamr/utils'
|
|
5
5
|
import { Url } from 'url'
|
|
6
|
-
import { GOING_AWAY } from './ClientWebsocket'
|
|
6
|
+
import { CUSTOM_GOING_AWAY, GOING_AWAY } from './ClientWebsocket'
|
|
7
7
|
|
|
8
8
|
const logger = new Logger(module)
|
|
9
9
|
|
|
@@ -29,37 +29,52 @@ export class ServerWebsocket extends EventEmitter<ConnectionEvents> implements I
|
|
|
29
29
|
constructor(socket: WsConnection, resourceURL: Url) {
|
|
30
30
|
super()
|
|
31
31
|
|
|
32
|
+
this.onMessage = this.onMessage.bind(this)
|
|
33
|
+
this.onClose = this.onClose.bind(this)
|
|
34
|
+
this.onError = this.onError.bind(this)
|
|
35
|
+
|
|
32
36
|
this.resourceURL = resourceURL
|
|
33
37
|
this.connectionId = new ConnectionID()
|
|
34
38
|
|
|
35
|
-
socket.on('message',
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
logger.debug('Received string Message: ' + message.utf8Data)
|
|
39
|
-
} else if (message.type === MessageType.BINARY) {
|
|
40
|
-
logger.trace('Received Binary Message of ' + message.binaryData.length + ' bytes')
|
|
41
|
-
this.emit('data',
|
|
42
|
-
new Uint8Array(message.binaryData.buffer, message.binaryData.byteOffset,
|
|
43
|
-
message.binaryData.byteLength / Uint8Array.BYTES_PER_ELEMENT))
|
|
44
|
-
}
|
|
45
|
-
})
|
|
46
|
-
socket.on('close', (reasonCode, description) => {
|
|
47
|
-
logger.trace('Peer ' + socket.remoteAddress + ' disconnected.')
|
|
48
|
-
this.doDisconnect(reasonCode, description)
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
socket.on('error', (error) => {
|
|
52
|
-
this.emit('error', error.name)
|
|
53
|
-
})
|
|
39
|
+
socket.on('message', this.onMessage)
|
|
40
|
+
socket.on('close', this.onClose)
|
|
41
|
+
socket.on('error', this.onError)
|
|
54
42
|
|
|
55
43
|
this.socket = socket
|
|
56
44
|
}
|
|
57
45
|
|
|
46
|
+
private onMessage(message: Message): void {
|
|
47
|
+
logger.trace('ServerWebsocket::onMessage')
|
|
48
|
+
if (message.type === MessageType.UTF8) {
|
|
49
|
+
logger.debug('Received string Message: ' + message.utf8Data)
|
|
50
|
+
} else if (message.type === MessageType.BINARY) {
|
|
51
|
+
logger.trace('Received Binary Message of ' + message.binaryData.length + ' bytes')
|
|
52
|
+
this.emit('data',
|
|
53
|
+
new Uint8Array(message.binaryData.buffer, message.binaryData.byteOffset,
|
|
54
|
+
message.binaryData.byteLength / Uint8Array.BYTES_PER_ELEMENT))
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
private onClose(reasonCode: number, description: string): void {
|
|
59
|
+
logger.trace('Peer ' + this.socket?.remoteAddress + ' disconnected.')
|
|
60
|
+
this.doDisconnect(reasonCode, description)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
private onError(error: Error): void {
|
|
64
|
+
this.emit('error', error.name)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private stopListening(): void {
|
|
68
|
+
this.socket?.off('message', this.onMessage)
|
|
69
|
+
this.socket?.off('close', this.onClose)
|
|
70
|
+
this.socket?.off('error', this.onError)
|
|
71
|
+
}
|
|
72
|
+
|
|
58
73
|
private doDisconnect(reasonCode: number, description: string): void {
|
|
59
74
|
this.stopped = true
|
|
60
|
-
this.
|
|
75
|
+
this.stopListening()
|
|
61
76
|
this.socket = undefined
|
|
62
|
-
const gracefulLeave = reasonCode === GOING_AWAY
|
|
77
|
+
const gracefulLeave = (reasonCode === GOING_AWAY) || (reasonCode === CUSTOM_GOING_AWAY)
|
|
63
78
|
this.emit('disconnected', gracefulLeave, reasonCode, description)
|
|
64
79
|
}
|
|
65
80
|
|
|
@@ -83,7 +98,7 @@ export class ServerWebsocket extends EventEmitter<ConnectionEvents> implements I
|
|
|
83
98
|
this.emit('disconnected', gracefulLeave, undefined, 'close() called')
|
|
84
99
|
this.removeAllListeners()
|
|
85
100
|
if (!this.stopped) {
|
|
86
|
-
this.socket?.close(gracefulLeave
|
|
101
|
+
this.socket?.close(gracefulLeave ? GOING_AWAY : undefined)
|
|
87
102
|
} else {
|
|
88
103
|
logger.debug('Tried to close a stopped connection')
|
|
89
104
|
}
|
|
@@ -93,7 +108,7 @@ export class ServerWebsocket extends EventEmitter<ConnectionEvents> implements I
|
|
|
93
108
|
if (!this.stopped) {
|
|
94
109
|
this.removeAllListeners()
|
|
95
110
|
if (this.socket) {
|
|
96
|
-
this.
|
|
111
|
+
this.stopListening()
|
|
97
112
|
this.socket.close()
|
|
98
113
|
this.socket = undefined
|
|
99
114
|
}
|