@matter/protocol 0.12.4-alpha.0-20250223-1e0341a1a → 0.12.4-alpha.0-20250224-46934b522
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/cjs/action/client/ClientInteraction.d.ts +38 -0
- package/dist/cjs/action/client/ClientInteraction.d.ts.map +1 -0
- package/dist/cjs/action/client/ClientInteraction.js +91 -0
- package/dist/cjs/action/client/ClientInteraction.js.map +6 -0
- package/dist/cjs/action/client/index.d.ts +7 -0
- package/dist/cjs/action/client/index.d.ts.map +1 -0
- package/dist/cjs/action/client/index.js +24 -0
- package/dist/cjs/action/client/index.js.map +6 -0
- package/dist/cjs/action/index.d.ts +1 -0
- package/dist/cjs/action/index.d.ts.map +1 -1
- package/dist/cjs/action/index.js +1 -0
- package/dist/cjs/action/index.js.map +1 -1
- package/dist/cjs/interaction/DecodedDataReport.d.ts +15 -0
- package/dist/cjs/interaction/DecodedDataReport.d.ts.map +1 -0
- package/dist/cjs/interaction/DecodedDataReport.js +42 -0
- package/dist/cjs/interaction/DecodedDataReport.js.map +6 -0
- package/dist/cjs/interaction/InteractionClient.d.ts +17 -23
- package/dist/cjs/interaction/InteractionClient.d.ts.map +1 -1
- package/dist/cjs/interaction/InteractionClient.js +100 -127
- package/dist/cjs/interaction/InteractionClient.js.map +1 -1
- package/dist/cjs/interaction/InteractionMessenger.d.ts +94 -1
- package/dist/cjs/interaction/InteractionMessenger.d.ts.map +1 -1
- package/dist/cjs/interaction/InteractionMessenger.js +56 -37
- package/dist/cjs/interaction/InteractionMessenger.js.map +1 -1
- package/dist/cjs/interaction/InteractionServer.d.ts +22 -3
- package/dist/cjs/interaction/InteractionServer.d.ts.map +1 -1
- package/dist/cjs/interaction/InteractionServer.js +129 -45
- package/dist/cjs/interaction/InteractionServer.js.map +1 -1
- package/dist/cjs/interaction/ServerSubscription.d.ts +8 -16
- package/dist/cjs/interaction/ServerSubscription.d.ts.map +1 -1
- package/dist/cjs/interaction/ServerSubscription.js +78 -55
- package/dist/cjs/interaction/ServerSubscription.js.map +1 -1
- package/dist/cjs/interaction/Subscription.d.ts +7 -1
- package/dist/cjs/interaction/Subscription.d.ts.map +1 -1
- package/dist/cjs/interaction/Subscription.js +25 -2
- package/dist/cjs/interaction/Subscription.js.map +1 -1
- package/dist/cjs/interaction/SubscriptionClient.d.ts +38 -0
- package/dist/cjs/interaction/SubscriptionClient.d.ts.map +1 -0
- package/dist/cjs/interaction/SubscriptionClient.js +98 -0
- package/dist/cjs/interaction/SubscriptionClient.js.map +6 -0
- package/dist/cjs/interaction/index.d.ts +1 -0
- package/dist/cjs/interaction/index.d.ts.map +1 -1
- package/dist/cjs/interaction/index.js +1 -0
- package/dist/cjs/interaction/index.js.map +1 -1
- package/dist/cjs/peer/ControllerCommissioner.d.ts +2 -2
- package/dist/cjs/peer/ControllerCommissioner.d.ts.map +1 -1
- package/dist/cjs/peer/ControllerCommissioner.js +7 -7
- package/dist/cjs/peer/ControllerCommissioner.js.map +1 -1
- package/dist/cjs/peer/InteractionQueue.d.ts +11 -0
- package/dist/cjs/peer/InteractionQueue.d.ts.map +1 -0
- package/dist/cjs/peer/InteractionQueue.js +42 -0
- package/dist/cjs/peer/InteractionQueue.js.map +6 -0
- package/dist/cjs/peer/PeerAddress.d.ts +5 -0
- package/dist/cjs/peer/PeerAddress.d.ts.map +1 -1
- package/dist/cjs/peer/PeerAddress.js +13 -1
- package/dist/cjs/peer/PeerAddress.js.map +1 -1
- package/dist/cjs/peer/PeerAddressStore.d.ts +1 -1
- package/dist/cjs/peer/PeerAddressStore.d.ts.map +1 -1
- package/dist/cjs/peer/PeerSet.d.ts +20 -7
- package/dist/cjs/peer/PeerSet.d.ts.map +1 -1
- package/dist/cjs/peer/PeerSet.js +74 -67
- package/dist/cjs/peer/PeerSet.js.map +1 -1
- package/dist/cjs/peer/PhysicalDeviceProperties.d.ts +26 -0
- package/dist/cjs/peer/PhysicalDeviceProperties.d.ts.map +1 -0
- package/dist/cjs/peer/PhysicalDeviceProperties.js +74 -0
- package/dist/cjs/peer/PhysicalDeviceProperties.js.map +6 -0
- package/dist/cjs/peer/index.d.ts +1 -0
- package/dist/cjs/peer/index.d.ts.map +1 -1
- package/dist/cjs/peer/index.js +1 -0
- package/dist/cjs/peer/index.js.map +1 -1
- package/dist/cjs/protocol/ExchangeManager.d.ts +1 -0
- package/dist/cjs/protocol/ExchangeManager.d.ts.map +1 -1
- package/dist/cjs/protocol/ExchangeManager.js +6 -3
- package/dist/cjs/protocol/ExchangeManager.js.map +1 -1
- package/dist/cjs/protocol/ExchangeProvider.d.ts +13 -1
- package/dist/cjs/protocol/ExchangeProvider.d.ts.map +1 -1
- package/dist/cjs/protocol/ExchangeProvider.js +2 -0
- package/dist/cjs/protocol/ExchangeProvider.js.map +1 -1
- package/dist/cjs/protocol/ProtocolHandler.d.ts +1 -1
- package/dist/cjs/protocol/ProtocolHandler.d.ts.map +1 -1
- package/dist/cjs/securechannel/SecureChannelMessenger.d.ts +1 -0
- package/dist/cjs/securechannel/SecureChannelMessenger.d.ts.map +1 -1
- package/dist/cjs/securechannel/SecureChannelMessenger.js +3 -0
- package/dist/cjs/securechannel/SecureChannelMessenger.js.map +1 -1
- package/dist/cjs/securechannel/SecureChannelProtocol.d.ts +1 -1
- package/dist/cjs/securechannel/SecureChannelProtocol.d.ts.map +1 -1
- package/dist/cjs/securechannel/SecureChannelProtocol.js +1 -3
- package/dist/cjs/securechannel/SecureChannelProtocol.js.map +1 -1
- package/dist/cjs/session/SecureSession.d.ts +1 -1
- package/dist/cjs/session/SecureSession.d.ts.map +1 -1
- package/dist/cjs/session/SecureSession.js +3 -2
- package/dist/cjs/session/SecureSession.js.map +1 -1
- package/dist/cjs/session/Session.d.ts +1 -0
- package/dist/cjs/session/Session.d.ts.map +1 -1
- package/dist/cjs/session/Session.js +1 -0
- package/dist/cjs/session/Session.js.map +1 -1
- package/dist/cjs/session/SessionManager.d.ts +2 -2
- package/dist/cjs/session/SessionManager.d.ts.map +1 -1
- package/dist/cjs/session/SessionManager.js +6 -9
- package/dist/cjs/session/SessionManager.js.map +1 -1
- package/dist/cjs/session/case/CaseServer.d.ts +1 -1
- package/dist/cjs/session/case/CaseServer.d.ts.map +1 -1
- package/dist/cjs/session/case/CaseServer.js +1 -3
- package/dist/cjs/session/case/CaseServer.js.map +1 -1
- package/dist/cjs/session/pase/PaseServer.d.ts +2 -3
- package/dist/cjs/session/pase/PaseServer.d.ts.map +1 -1
- package/dist/cjs/session/pase/PaseServer.js +12 -14
- package/dist/cjs/session/pase/PaseServer.js.map +1 -1
- package/dist/esm/action/client/ClientInteraction.d.ts +38 -0
- package/dist/esm/action/client/ClientInteraction.d.ts.map +1 -0
- package/dist/esm/action/client/ClientInteraction.js +71 -0
- package/dist/esm/action/client/ClientInteraction.js.map +6 -0
- package/dist/esm/action/client/index.d.ts +7 -0
- package/dist/esm/action/client/index.d.ts.map +1 -0
- package/dist/esm/action/client/index.js +7 -0
- package/dist/esm/action/client/index.js.map +6 -0
- package/dist/esm/action/index.d.ts +1 -0
- package/dist/esm/action/index.d.ts.map +1 -1
- package/dist/esm/action/index.js +1 -0
- package/dist/esm/action/index.js.map +1 -1
- package/dist/esm/interaction/DecodedDataReport.d.ts +15 -0
- package/dist/esm/interaction/DecodedDataReport.d.ts.map +1 -0
- package/dist/esm/interaction/DecodedDataReport.js +22 -0
- package/dist/esm/interaction/DecodedDataReport.js.map +6 -0
- package/dist/esm/interaction/InteractionClient.d.ts +17 -23
- package/dist/esm/interaction/InteractionClient.d.ts.map +1 -1
- package/dist/esm/interaction/InteractionClient.js +102 -134
- package/dist/esm/interaction/InteractionClient.js.map +1 -1
- package/dist/esm/interaction/InteractionMessenger.d.ts +94 -1
- package/dist/esm/interaction/InteractionMessenger.d.ts.map +1 -1
- package/dist/esm/interaction/InteractionMessenger.js +56 -37
- package/dist/esm/interaction/InteractionMessenger.js.map +1 -1
- package/dist/esm/interaction/InteractionServer.d.ts +22 -3
- package/dist/esm/interaction/InteractionServer.d.ts.map +1 -1
- package/dist/esm/interaction/InteractionServer.js +130 -46
- package/dist/esm/interaction/InteractionServer.js.map +1 -1
- package/dist/esm/interaction/ServerSubscription.d.ts +8 -16
- package/dist/esm/interaction/ServerSubscription.d.ts.map +1 -1
- package/dist/esm/interaction/ServerSubscription.js +78 -55
- package/dist/esm/interaction/ServerSubscription.js.map +1 -1
- package/dist/esm/interaction/Subscription.d.ts +7 -1
- package/dist/esm/interaction/Subscription.d.ts.map +1 -1
- package/dist/esm/interaction/Subscription.js +26 -3
- package/dist/esm/interaction/Subscription.js.map +1 -1
- package/dist/esm/interaction/SubscriptionClient.d.ts +38 -0
- package/dist/esm/interaction/SubscriptionClient.d.ts.map +1 -0
- package/dist/esm/interaction/SubscriptionClient.js +78 -0
- package/dist/esm/interaction/SubscriptionClient.js.map +6 -0
- package/dist/esm/interaction/index.d.ts +1 -0
- package/dist/esm/interaction/index.d.ts.map +1 -1
- package/dist/esm/interaction/index.js +1 -0
- package/dist/esm/interaction/index.js.map +1 -1
- package/dist/esm/peer/ControllerCommissioner.d.ts +2 -2
- package/dist/esm/peer/ControllerCommissioner.d.ts.map +1 -1
- package/dist/esm/peer/ControllerCommissioner.js +9 -9
- package/dist/esm/peer/ControllerCommissioner.js.map +1 -1
- package/dist/esm/peer/InteractionQueue.d.ts +11 -0
- package/dist/esm/peer/InteractionQueue.d.ts.map +1 -0
- package/dist/esm/peer/InteractionQueue.js +22 -0
- package/dist/esm/peer/InteractionQueue.js.map +6 -0
- package/dist/esm/peer/PeerAddress.d.ts +5 -0
- package/dist/esm/peer/PeerAddress.d.ts.map +1 -1
- package/dist/esm/peer/PeerAddress.js +13 -1
- package/dist/esm/peer/PeerAddress.js.map +1 -1
- package/dist/esm/peer/PeerAddressStore.d.ts +1 -1
- package/dist/esm/peer/PeerAddressStore.d.ts.map +1 -1
- package/dist/esm/peer/PeerSet.d.ts +20 -7
- package/dist/esm/peer/PeerSet.d.ts.map +1 -1
- package/dist/esm/peer/PeerSet.js +75 -68
- package/dist/esm/peer/PeerSet.js.map +1 -1
- package/dist/esm/peer/PhysicalDeviceProperties.d.ts +26 -0
- package/dist/esm/peer/PhysicalDeviceProperties.d.ts.map +1 -0
- package/dist/esm/peer/PhysicalDeviceProperties.js +54 -0
- package/dist/esm/peer/PhysicalDeviceProperties.js.map +6 -0
- package/dist/esm/peer/index.d.ts +1 -0
- package/dist/esm/peer/index.d.ts.map +1 -1
- package/dist/esm/peer/index.js +1 -0
- package/dist/esm/peer/index.js.map +1 -1
- package/dist/esm/protocol/ExchangeManager.d.ts +1 -0
- package/dist/esm/protocol/ExchangeManager.d.ts.map +1 -1
- package/dist/esm/protocol/ExchangeManager.js +6 -3
- package/dist/esm/protocol/ExchangeManager.js.map +1 -1
- package/dist/esm/protocol/ExchangeProvider.d.ts +13 -1
- package/dist/esm/protocol/ExchangeProvider.d.ts.map +1 -1
- package/dist/esm/protocol/ExchangeProvider.js +2 -0
- package/dist/esm/protocol/ExchangeProvider.js.map +1 -1
- package/dist/esm/protocol/ProtocolHandler.d.ts +1 -1
- package/dist/esm/protocol/ProtocolHandler.d.ts.map +1 -1
- package/dist/esm/securechannel/SecureChannelMessenger.d.ts +1 -0
- package/dist/esm/securechannel/SecureChannelMessenger.d.ts.map +1 -1
- package/dist/esm/securechannel/SecureChannelMessenger.js +3 -0
- package/dist/esm/securechannel/SecureChannelMessenger.js.map +1 -1
- package/dist/esm/securechannel/SecureChannelProtocol.d.ts +1 -1
- package/dist/esm/securechannel/SecureChannelProtocol.d.ts.map +1 -1
- package/dist/esm/securechannel/SecureChannelProtocol.js +1 -3
- package/dist/esm/securechannel/SecureChannelProtocol.js.map +1 -1
- package/dist/esm/session/SecureSession.d.ts +1 -1
- package/dist/esm/session/SecureSession.d.ts.map +1 -1
- package/dist/esm/session/SecureSession.js +3 -2
- package/dist/esm/session/SecureSession.js.map +1 -1
- package/dist/esm/session/Session.d.ts +1 -0
- package/dist/esm/session/Session.d.ts.map +1 -1
- package/dist/esm/session/Session.js +1 -0
- package/dist/esm/session/Session.js.map +1 -1
- package/dist/esm/session/SessionManager.d.ts +2 -2
- package/dist/esm/session/SessionManager.d.ts.map +1 -1
- package/dist/esm/session/SessionManager.js +7 -10
- package/dist/esm/session/SessionManager.js.map +1 -1
- package/dist/esm/session/case/CaseServer.d.ts +1 -1
- package/dist/esm/session/case/CaseServer.d.ts.map +1 -1
- package/dist/esm/session/case/CaseServer.js +1 -3
- package/dist/esm/session/case/CaseServer.js.map +1 -1
- package/dist/esm/session/pase/PaseServer.d.ts +2 -3
- package/dist/esm/session/pase/PaseServer.d.ts.map +1 -1
- package/dist/esm/session/pase/PaseServer.js +12 -14
- package/dist/esm/session/pase/PaseServer.js.map +1 -1
- package/package.json +6 -6
- package/src/action/client/ClientInteraction.ts +110 -0
- package/src/action/client/index.ts +7 -0
- package/src/action/index.ts +1 -0
- package/src/interaction/DecodedDataReport.ts +29 -0
- package/src/interaction/InteractionClient.ts +118 -165
- package/src/interaction/InteractionMessenger.ts +63 -43
- package/src/interaction/InteractionServer.ts +176 -50
- package/src/interaction/ServerSubscription.ts +87 -63
- package/src/interaction/Subscription.ts +34 -6
- package/src/interaction/SubscriptionClient.ts +107 -0
- package/src/interaction/index.ts +1 -0
- package/src/peer/ControllerCommissioner.ts +10 -10
- package/src/peer/InteractionQueue.ts +22 -0
- package/src/peer/PeerAddress.ts +14 -0
- package/src/peer/PeerAddressStore.ts +1 -1
- package/src/peer/PeerSet.ts +98 -83
- package/src/peer/PhysicalDeviceProperties.ts +80 -0
- package/src/peer/index.ts +1 -0
- package/src/protocol/ExchangeManager.ts +7 -3
- package/src/protocol/ExchangeProvider.ts +14 -1
- package/src/protocol/ProtocolHandler.ts +1 -1
- package/src/securechannel/SecureChannelMessenger.ts +4 -0
- package/src/securechannel/SecureChannelProtocol.ts +1 -3
- package/src/session/SecureSession.ts +3 -2
- package/src/session/Session.ts +1 -0
- package/src/session/SessionManager.ts +6 -9
- package/src/session/case/CaseServer.ts +2 -4
- package/src/session/pase/PaseServer.ts +13 -15
package/src/peer/PeerSet.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import { DiscoveryData, ScannerSet } from "#common/Scanner.js";
|
|
8
8
|
import {
|
|
9
9
|
anyPromise,
|
|
10
|
+
AsyncObservable,
|
|
10
11
|
BasicSet,
|
|
11
12
|
ChannelType,
|
|
12
13
|
Construction,
|
|
@@ -22,13 +23,12 @@ import {
|
|
|
22
23
|
NetInterfaceSet,
|
|
23
24
|
NoResponseTimeoutError,
|
|
24
25
|
ObservableSet,
|
|
25
|
-
PromiseQueue,
|
|
26
26
|
ServerAddressIp,
|
|
27
27
|
serverAddressToString,
|
|
28
28
|
Time,
|
|
29
29
|
Timer,
|
|
30
30
|
} from "#general";
|
|
31
|
-
import {
|
|
31
|
+
import { SubscriptionClient } from "#interaction/SubscriptionClient.js";
|
|
32
32
|
import { MdnsScanner } from "#mdns/MdnsScanner.js";
|
|
33
33
|
import { PeerAddress, PeerAddressMap } from "#peer/PeerAddress.js";
|
|
34
34
|
import { CaseClient, SecureSession, Session } from "#session/index.js";
|
|
@@ -39,6 +39,7 @@ import { ChannelNotConnectedError, ExchangeManager, MessageChannel } from "../pr
|
|
|
39
39
|
import { ReconnectableExchangeProvider } from "../protocol/ExchangeProvider.js";
|
|
40
40
|
import { RetransmissionLimitReachedError } from "../protocol/MessageExchange.js";
|
|
41
41
|
import { ControllerDiscovery, DiscoveryError, PairRetransmissionLimitReachedError } from "./ControllerDiscovery.js";
|
|
42
|
+
import { InteractionQueue } from "./InteractionQueue.js";
|
|
42
43
|
import { OperationalPeer } from "./OperationalPeer.js";
|
|
43
44
|
import { PeerAddressStore, PeerDataStore } from "./PeerAddressStore.js";
|
|
44
45
|
|
|
@@ -47,9 +48,6 @@ const logger = Logger.get("PeerSet");
|
|
|
47
48
|
const RECONNECTION_POLLING_INTERVAL_MS = 600_000; // 10 minutes
|
|
48
49
|
const RETRANSMISSION_DISCOVERY_TIMEOUT_S = 5;
|
|
49
50
|
|
|
50
|
-
const CONCURRENT_QUEUED_INTERACTIONS = 4;
|
|
51
|
-
const INTERACTION_QUEUE_DELAY_MS = 100;
|
|
52
|
-
|
|
53
51
|
/**
|
|
54
52
|
* Types of discovery that may be performed when connecting operationally.
|
|
55
53
|
*/
|
|
@@ -93,6 +91,7 @@ export interface PeerSetContext {
|
|
|
93
91
|
sessions: SessionManager;
|
|
94
92
|
channels: ChannelManager;
|
|
95
93
|
exchanges: ExchangeManager;
|
|
94
|
+
subscriptionClient: SubscriptionClient;
|
|
96
95
|
scanners: ScannerSet;
|
|
97
96
|
netInterfaces: NetInterfaceSet;
|
|
98
97
|
store: PeerAddressStore;
|
|
@@ -105,6 +104,7 @@ export class PeerSet implements ImmutableSet<OperationalPeer>, ObservableSet<Ope
|
|
|
105
104
|
readonly #sessions: SessionManager;
|
|
106
105
|
readonly #channels: ChannelManager;
|
|
107
106
|
readonly #exchanges: ExchangeManager;
|
|
107
|
+
readonly #subscriptionClient: SubscriptionClient;
|
|
108
108
|
readonly #scanners: ScannerSet;
|
|
109
109
|
readonly #netInterfaces: NetInterfaceSet;
|
|
110
110
|
readonly #caseClient: CaseClient;
|
|
@@ -117,16 +117,17 @@ export class PeerSet implements ImmutableSet<OperationalPeer>, ObservableSet<Ope
|
|
|
117
117
|
}>();
|
|
118
118
|
readonly #construction: Construction<PeerSet>;
|
|
119
119
|
readonly #store: PeerAddressStore;
|
|
120
|
-
readonly #interactionQueue = new
|
|
120
|
+
readonly #interactionQueue = new InteractionQueue();
|
|
121
121
|
readonly #nodeCachedData = new PeerAddressMap<PeerDataStore>(); // Temporarily until we store it in new API
|
|
122
|
-
readonly #
|
|
122
|
+
readonly #disconnected = AsyncObservable<[address: PeerAddress]>();
|
|
123
123
|
|
|
124
124
|
constructor(context: PeerSetContext) {
|
|
125
|
-
const { sessions, channels, exchanges, scanners, netInterfaces, store } = context;
|
|
125
|
+
const { sessions, channels, exchanges, subscriptionClient, scanners, netInterfaces, store } = context;
|
|
126
126
|
|
|
127
127
|
this.#sessions = sessions;
|
|
128
128
|
this.#channels = channels;
|
|
129
129
|
this.#exchanges = exchanges;
|
|
130
|
+
this.#subscriptionClient = subscriptionClient;
|
|
130
131
|
this.#scanners = scanners;
|
|
131
132
|
this.#netInterfaces = netInterfaces;
|
|
132
133
|
this.#store = store;
|
|
@@ -143,6 +144,7 @@ export class PeerSet implements ImmutableSet<OperationalPeer>, ObservableSet<Ope
|
|
|
143
144
|
|
|
144
145
|
this.#sessions.resubmissionStarted.on(this.#handleResubmissionStarted.bind(this));
|
|
145
146
|
|
|
147
|
+
/** A channel was added by ourselves */
|
|
146
148
|
this.#channels.added.on((address, msgChannel) => {
|
|
147
149
|
if (isIpNetworkChannel(msgChannel.channel)) {
|
|
148
150
|
// Update the channel address if it has one
|
|
@@ -165,6 +167,10 @@ export class PeerSet implements ImmutableSet<OperationalPeer>, ObservableSet<Ope
|
|
|
165
167
|
return this.#peers.deleted;
|
|
166
168
|
}
|
|
167
169
|
|
|
170
|
+
get disconnected() {
|
|
171
|
+
return this.#disconnected;
|
|
172
|
+
}
|
|
173
|
+
|
|
168
174
|
has(item: PeerAddress | OperationalPeer) {
|
|
169
175
|
if ("address" in item) {
|
|
170
176
|
return this.#peers.has(item);
|
|
@@ -201,6 +207,7 @@ export class PeerSet implements ImmutableSet<OperationalPeer>, ObservableSet<Ope
|
|
|
201
207
|
sessions: env.get(SessionManager),
|
|
202
208
|
channels: env.get(ChannelManager),
|
|
203
209
|
exchanges: env.get(ExchangeManager),
|
|
210
|
+
subscriptionClient: env.get(SubscriptionClient),
|
|
204
211
|
scanners: env.get(ScannerSet),
|
|
205
212
|
netInterfaces: env.get(NetInterfaceSet),
|
|
206
213
|
store: env.get(PeerAddressStore),
|
|
@@ -213,20 +220,26 @@ export class PeerSet implements ImmutableSet<OperationalPeer>, ObservableSet<Ope
|
|
|
213
220
|
return this.#peers;
|
|
214
221
|
}
|
|
215
222
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
async connect(
|
|
220
|
-
address: PeerAddress,
|
|
221
|
-
discoveryOptions: DiscoveryOptions,
|
|
222
|
-
allowUnknownPeer = false,
|
|
223
|
-
): Promise<InteractionClient> {
|
|
224
|
-
await this.#ensureConnection(address, discoveryOptions, allowUnknownPeer);
|
|
223
|
+
get subscriptionClient() {
|
|
224
|
+
return this.#subscriptionClient;
|
|
225
|
+
}
|
|
225
226
|
|
|
226
|
-
|
|
227
|
+
get interactionQueue() {
|
|
228
|
+
return this.#interactionQueue;
|
|
227
229
|
}
|
|
228
230
|
|
|
229
|
-
|
|
231
|
+
/**
|
|
232
|
+
* Ensure there is a channel to the designated peer.
|
|
233
|
+
*/
|
|
234
|
+
async ensureConnection(
|
|
235
|
+
address: PeerAddress,
|
|
236
|
+
options: {
|
|
237
|
+
discoveryOptions: DiscoveryOptions;
|
|
238
|
+
allowUnknownPeer?: boolean;
|
|
239
|
+
operationalAddress?: ServerAddressIp;
|
|
240
|
+
},
|
|
241
|
+
) {
|
|
242
|
+
const { discoveryOptions, allowUnknownPeer, operationalAddress } = options;
|
|
230
243
|
if (!this.#peersByAddress.has(address) && !allowUnknownPeer) {
|
|
231
244
|
throw new UnknownNodeError(`Cannot connect to unknown device ${PeerAddress(address)}`);
|
|
232
245
|
}
|
|
@@ -242,7 +255,7 @@ export class PeerSet implements ImmutableSet<OperationalPeer>, ObservableSet<Ope
|
|
|
242
255
|
const { promise, resolver, rejecter } = createPromise<MessageChannel>();
|
|
243
256
|
this.#runningPeerReconnections.set(address, { promise, rejecter });
|
|
244
257
|
|
|
245
|
-
this.#resume(address, discoveryOptions)
|
|
258
|
+
this.#resume(address, discoveryOptions, operationalAddress)
|
|
246
259
|
.then(channel => {
|
|
247
260
|
this.#runningPeerReconnections.delete(address);
|
|
248
261
|
resolver(channel);
|
|
@@ -256,62 +269,46 @@ export class PeerSet implements ImmutableSet<OperationalPeer>, ObservableSet<Ope
|
|
|
256
269
|
}
|
|
257
270
|
}
|
|
258
271
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
const nodeStore = this.get(address)?.dataStore;
|
|
266
|
-
await nodeStore?.construction; // Lazy initialize the data if not already done
|
|
267
|
-
|
|
272
|
+
/**
|
|
273
|
+
* Obtain an exchange provider for the designated peer.
|
|
274
|
+
*/
|
|
275
|
+
async exchangeProviderFor(address: PeerAddress, discoveryOptions?: DiscoveryOptions) {
|
|
268
276
|
let initiallyConnected = this.#channels.hasChannel(address);
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
277
|
+
return new ReconnectableExchangeProvider(this.#exchanges, this.#channels, address, async () => {
|
|
278
|
+
if (!initiallyConnected && !this.#channels.hasChannel(address)) {
|
|
279
|
+
// We got an uninitialized node, so do the first connection as usual
|
|
280
|
+
await this.ensureConnection(address, {
|
|
281
|
+
discoveryOptions: { discoveryType: NodeDiscoveryType.None },
|
|
282
|
+
});
|
|
283
|
+
initiallyConnected = true; // We only do this connection once, rest is handled in following code
|
|
284
|
+
if (this.#channels.hasChannel(address)) {
|
|
285
|
+
return;
|
|
278
286
|
}
|
|
287
|
+
}
|
|
279
288
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
}
|
|
285
|
-
await this.#channels.removeAllNodeChannels(address);
|
|
289
|
+
if (!this.#channels.hasChannel(address)) {
|
|
290
|
+
throw new RetransmissionLimitReachedError(`Device ${PeerAddress(address)} is currently not reachable.`);
|
|
291
|
+
}
|
|
292
|
+
await this.#channels.removeAllNodeChannels(address);
|
|
286
293
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
) {
|
|
306
|
-
throw new RetransmissionLimitReachedError(`${PeerAddress(address)} is not reachable.`);
|
|
307
|
-
}
|
|
308
|
-
}),
|
|
309
|
-
address,
|
|
310
|
-
this.#interactionQueue,
|
|
311
|
-
nodeStore,
|
|
312
|
-
);
|
|
313
|
-
this.#clients.set(address, client);
|
|
314
|
-
return client;
|
|
294
|
+
// Enrich discoveryData with data from the node store when not provided
|
|
295
|
+
const { discoveryData } = discoveryOptions ?? {
|
|
296
|
+
discoveryData: this.#peersByAddress.get(address)?.discoveryData,
|
|
297
|
+
};
|
|
298
|
+
// Try to use first result for one last try before we need to reconnect
|
|
299
|
+
const operationalAddress = this.#knownOperationalAddressFor(address, true);
|
|
300
|
+
if (operationalAddress === undefined) {
|
|
301
|
+
logger.info(
|
|
302
|
+
`Re-discovering device failed (no address found), remove all sessions for ${PeerAddress(address)}`,
|
|
303
|
+
);
|
|
304
|
+
// We remove all sessions, this also informs the PairedNode class
|
|
305
|
+
await this.#sessions.removeAllSessionsForNode(address);
|
|
306
|
+
throw new RetransmissionLimitReachedError(`No operational address found for ${PeerAddress(address)}`);
|
|
307
|
+
}
|
|
308
|
+
if ((await this.#reconnectKnownAddress(address, operationalAddress, discoveryData, 2_000)) === undefined) {
|
|
309
|
+
throw new RetransmissionLimitReachedError(`${PeerAddress(address)} is not reachable.`);
|
|
310
|
+
}
|
|
311
|
+
});
|
|
315
312
|
}
|
|
316
313
|
|
|
317
314
|
/**
|
|
@@ -327,10 +324,15 @@ export class PeerSet implements ImmutableSet<OperationalPeer>, ObservableSet<Ope
|
|
|
327
324
|
/**
|
|
328
325
|
* Terminate any active peer connection.
|
|
329
326
|
*/
|
|
330
|
-
async disconnect(
|
|
331
|
-
this
|
|
327
|
+
async disconnect(peer: PeerAddress | OperationalPeer, sendSessionClose = true) {
|
|
328
|
+
const address = this.get(peer)?.address;
|
|
329
|
+
if (address === undefined) {
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
|
|
332
333
|
await this.#sessions.removeAllSessionsForNode(address, sendSessionClose);
|
|
333
334
|
await this.#channels.removeAllNodeChannels(address);
|
|
335
|
+
await this.#disconnected.emit(address);
|
|
334
336
|
}
|
|
335
337
|
|
|
336
338
|
/**
|
|
@@ -348,7 +350,6 @@ export class PeerSet implements ImmutableSet<OperationalPeer>, ObservableSet<Ope
|
|
|
348
350
|
await this.#store.deletePeer(address);
|
|
349
351
|
await this.disconnect(address, false);
|
|
350
352
|
await this.#sessions.deleteResumptionRecord(address);
|
|
351
|
-
this.#clients.delete(address);
|
|
352
353
|
}
|
|
353
354
|
|
|
354
355
|
async close() {
|
|
@@ -358,8 +359,11 @@ export class PeerSet implements ImmutableSet<OperationalPeer>, ObservableSet<Ope
|
|
|
358
359
|
// This ends discovery without triggering promises
|
|
359
360
|
mdnsScanner?.cancelOperationalDeviceDiscovery(this.#sessions.fabricFor(address), address.nodeId, false);
|
|
360
361
|
}
|
|
361
|
-
|
|
362
|
-
this.#
|
|
362
|
+
|
|
363
|
+
for (const { address } of this.#peers) {
|
|
364
|
+
await this.disconnect(address, false);
|
|
365
|
+
}
|
|
366
|
+
|
|
363
367
|
this.#interactionQueue.close();
|
|
364
368
|
this.#runningPeerReconnections.forEach(({ rejecter }) =>
|
|
365
369
|
rejecter(new ChannelNotConnectedError("PeerSet closed")),
|
|
@@ -373,18 +377,22 @@ export class PeerSet implements ImmutableSet<OperationalPeer>, ObservableSet<Ope
|
|
|
373
377
|
* device is discovered again using its operational instance details.
|
|
374
378
|
* It returns the operational MessageChannel on success.
|
|
375
379
|
*/
|
|
376
|
-
async #resume(address: PeerAddress, discoveryOptions?: DiscoveryOptions) {
|
|
380
|
+
async #resume(address: PeerAddress, discoveryOptions?: DiscoveryOptions, tryOperationalAddress?: ServerAddressIp) {
|
|
377
381
|
const { discoveryType } = discoveryOptions ?? {};
|
|
382
|
+
|
|
378
383
|
const operationalAddress =
|
|
379
|
-
|
|
384
|
+
tryOperationalAddress ??
|
|
385
|
+
(discoveryType === NodeDiscoveryType.None
|
|
380
386
|
? this.#getLastOperationalAddress(address)
|
|
381
|
-
: this.#knownOperationalAddressFor(address);
|
|
387
|
+
: this.#knownOperationalAddressFor(address));
|
|
388
|
+
|
|
382
389
|
try {
|
|
383
390
|
return await this.#connectOrDiscoverNode(address, operationalAddress, discoveryOptions);
|
|
384
391
|
} catch (error) {
|
|
385
392
|
if (
|
|
386
393
|
(error instanceof DiscoveryError || error instanceof NoResponseTimeoutError) &&
|
|
387
|
-
this.#peersByAddress.has(address)
|
|
394
|
+
this.#peersByAddress.has(address) &&
|
|
395
|
+
tryOperationalAddress === undefined
|
|
388
396
|
) {
|
|
389
397
|
logger.info(`Resume failed, remove all sessions for ${PeerAddress(address)}`);
|
|
390
398
|
// We remove all sessions, this also informs the PairedNode class
|
|
@@ -439,7 +447,13 @@ export class PeerSet implements ImmutableSet<OperationalPeer>, ObservableSet<Ope
|
|
|
439
447
|
operationalAddress !== undefined &&
|
|
440
448
|
(runningDiscoveryType === NodeDiscoveryType.None || requestedDiscoveryType === NodeDiscoveryType.None)
|
|
441
449
|
) {
|
|
442
|
-
const directReconnection = await this.#reconnectKnownAddress(
|
|
450
|
+
const directReconnection = await this.#reconnectKnownAddress(
|
|
451
|
+
address,
|
|
452
|
+
operationalAddress,
|
|
453
|
+
discoveryData,
|
|
454
|
+
// When we use a timeout for discovery also use this for reconnecting to the node
|
|
455
|
+
timeoutSeconds ? timeoutSeconds * 1000 : undefined,
|
|
456
|
+
);
|
|
443
457
|
if (directReconnection !== undefined) {
|
|
444
458
|
return directReconnection;
|
|
445
459
|
}
|
|
@@ -574,6 +588,7 @@ export class PeerSet implements ImmutableSet<OperationalPeer>, ObservableSet<Ope
|
|
|
574
588
|
address = PeerAddress(address);
|
|
575
589
|
|
|
576
590
|
const { ip, port } = operationalAddress;
|
|
591
|
+
const startTime = Time.nowMs();
|
|
577
592
|
try {
|
|
578
593
|
logger.debug(
|
|
579
594
|
`Resuming connection to ${PeerAddress(address)} at ${ip}:${port}${
|
|
@@ -592,7 +607,7 @@ export class PeerSet implements ImmutableSet<OperationalPeer>, ObservableSet<Ope
|
|
|
592
607
|
error,
|
|
593
608
|
);
|
|
594
609
|
// We remove all sessions, this also informs the PairedNode class
|
|
595
|
-
await this.#sessions.removeAllSessionsForNode(address);
|
|
610
|
+
await this.#sessions.removeAllSessionsForNode(address, false, startTime);
|
|
596
611
|
return undefined;
|
|
597
612
|
} else {
|
|
598
613
|
throw error;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2025 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Logger } from "#general";
|
|
8
|
+
|
|
9
|
+
const logger = Logger.get("PhysicalDeviceProperties");
|
|
10
|
+
|
|
11
|
+
const DEFAULT_SUBSCRIPTION_FLOOR_DEFAULT_S = 1;
|
|
12
|
+
const DEFAULT_SUBSCRIPTION_FLOOR_ICD_S = 0;
|
|
13
|
+
const DEFAULT_SUBSCRIPTION_CEILING_WIFI_S = 60;
|
|
14
|
+
const DEFAULT_SUBSCRIPTION_CEILING_THREAD_S = 60;
|
|
15
|
+
const DEFAULT_SUBSCRIPTION_CEILING_THREAD_SLEEPY_S = 180;
|
|
16
|
+
const DEFAULT_SUBSCRIPTION_CEILING_BATTERY_POWERED_S = 600;
|
|
17
|
+
|
|
18
|
+
export interface PhysicalDeviceProperties {
|
|
19
|
+
threadConnected: boolean;
|
|
20
|
+
wifiConnected: boolean;
|
|
21
|
+
ethernetConnected: boolean;
|
|
22
|
+
rootEndpointServerList: number[];
|
|
23
|
+
isBatteryPowered: boolean;
|
|
24
|
+
isIntermittentlyConnected: boolean;
|
|
25
|
+
isThreadSleepyEndDevice: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export namespace PhysicalDeviceProperties {
|
|
29
|
+
export function determineSubscriptionParameters(options?: {
|
|
30
|
+
properties?: PhysicalDeviceProperties;
|
|
31
|
+
description?: string;
|
|
32
|
+
subscribeMinIntervalFloorSeconds?: number;
|
|
33
|
+
subscribeMaxIntervalCeilingSeconds?: number;
|
|
34
|
+
}) {
|
|
35
|
+
const { properties } = options ?? {};
|
|
36
|
+
|
|
37
|
+
let {
|
|
38
|
+
description,
|
|
39
|
+
subscribeMinIntervalFloorSeconds: minIntervalFloorSeconds,
|
|
40
|
+
subscribeMaxIntervalCeilingSeconds: maxIntervalCeilingSeconds,
|
|
41
|
+
} = options ?? {};
|
|
42
|
+
|
|
43
|
+
if (description === undefined) {
|
|
44
|
+
description = "Node";
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const { isBatteryPowered, isIntermittentlyConnected, threadConnected, isThreadSleepyEndDevice } =
|
|
48
|
+
properties ?? {};
|
|
49
|
+
|
|
50
|
+
if (isIntermittentlyConnected) {
|
|
51
|
+
if (minIntervalFloorSeconds !== undefined && minIntervalFloorSeconds !== DEFAULT_SUBSCRIPTION_FLOOR_ICD_S) {
|
|
52
|
+
logger.info(
|
|
53
|
+
`${description}: Overwriting minIntervalFloorSeconds for intermittently connected device to ${DEFAULT_SUBSCRIPTION_FLOOR_ICD_S}`,
|
|
54
|
+
);
|
|
55
|
+
minIntervalFloorSeconds = DEFAULT_SUBSCRIPTION_FLOOR_ICD_S;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const defaultCeiling = isBatteryPowered
|
|
60
|
+
? DEFAULT_SUBSCRIPTION_CEILING_BATTERY_POWERED_S
|
|
61
|
+
: isThreadSleepyEndDevice
|
|
62
|
+
? DEFAULT_SUBSCRIPTION_CEILING_THREAD_SLEEPY_S
|
|
63
|
+
: threadConnected
|
|
64
|
+
? DEFAULT_SUBSCRIPTION_CEILING_THREAD_S
|
|
65
|
+
: DEFAULT_SUBSCRIPTION_CEILING_WIFI_S;
|
|
66
|
+
if (maxIntervalCeilingSeconds === undefined) {
|
|
67
|
+
maxIntervalCeilingSeconds = defaultCeiling;
|
|
68
|
+
}
|
|
69
|
+
if (maxIntervalCeilingSeconds < defaultCeiling) {
|
|
70
|
+
logger.debug(
|
|
71
|
+
`${description}: maxIntervalCeilingSeconds ideally is ${defaultCeiling}s instead of ${maxIntervalCeilingSeconds}s due to device type`,
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
minIntervalFloorSeconds: minIntervalFloorSeconds ?? DEFAULT_SUBSCRIPTION_FLOOR_DEFAULT_S,
|
|
77
|
+
maxIntervalCeilingSeconds,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
package/src/peer/index.ts
CHANGED
|
@@ -150,6 +150,10 @@ export class ExchangeManager {
|
|
|
150
150
|
return instance;
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
+
get channels() {
|
|
154
|
+
return this.#channelManager;
|
|
155
|
+
}
|
|
156
|
+
|
|
153
157
|
hasProtocolHandler(protocolId: number) {
|
|
154
158
|
return this.#protocols.has(protocolId);
|
|
155
159
|
}
|
|
@@ -159,10 +163,10 @@ export class ExchangeManager {
|
|
|
159
163
|
}
|
|
160
164
|
|
|
161
165
|
addProtocolHandler(protocol: ProtocolHandler) {
|
|
162
|
-
if (this.hasProtocolHandler(protocol.
|
|
163
|
-
throw new ImplementationError(`Handler for protocol ${protocol.
|
|
166
|
+
if (this.hasProtocolHandler(protocol.id)) {
|
|
167
|
+
throw new ImplementationError(`Handler for protocol ${protocol.id} already registered.`);
|
|
164
168
|
}
|
|
165
|
-
this.#protocols.set(protocol.
|
|
169
|
+
this.#protocols.set(protocol.id, protocol);
|
|
166
170
|
}
|
|
167
171
|
|
|
168
172
|
initiateExchange(address: PeerAddress, protocolId: number) {
|
|
@@ -12,8 +12,13 @@ import { MessageExchange } from "../protocol/MessageExchange.js";
|
|
|
12
12
|
import { ProtocolHandler } from "../protocol/ProtocolHandler.js";
|
|
13
13
|
import { Session } from "../session/Session.js";
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Interface for obtaining an exchange with a specific peer.
|
|
17
|
+
*/
|
|
15
18
|
export abstract class ExchangeProvider {
|
|
16
|
-
|
|
19
|
+
abstract readonly supportsReconnect: boolean;
|
|
20
|
+
|
|
21
|
+
constructor(protected readonly exchangeManager: ExchangeManager) {}
|
|
17
22
|
|
|
18
23
|
hasProtocolHandler(protocolId: number) {
|
|
19
24
|
return this.exchangeManager.hasProtocolHandler(protocolId);
|
|
@@ -33,8 +38,12 @@ export abstract class ExchangeProvider {
|
|
|
33
38
|
abstract channelType: ChannelType;
|
|
34
39
|
}
|
|
35
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Manages an exchange over an established channel.
|
|
43
|
+
*/
|
|
36
44
|
export class DedicatedChannelExchangeProvider extends ExchangeProvider {
|
|
37
45
|
#channel: MessageChannel;
|
|
46
|
+
readonly supportsReconnect = false;
|
|
38
47
|
|
|
39
48
|
constructor(exchangeManager: ExchangeManager, channel: MessageChannel) {
|
|
40
49
|
super(exchangeManager);
|
|
@@ -58,7 +67,11 @@ export class DedicatedChannelExchangeProvider extends ExchangeProvider {
|
|
|
58
67
|
}
|
|
59
68
|
}
|
|
60
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Manages peer exchange that will reestablish automatically in the case of communication failure.
|
|
72
|
+
*/
|
|
61
73
|
export class ReconnectableExchangeProvider extends ExchangeProvider {
|
|
74
|
+
readonly supportsReconnect = true;
|
|
62
75
|
readonly #address: PeerAddress;
|
|
63
76
|
readonly #reconnectChannelFunc: () => Promise<void>;
|
|
64
77
|
readonly #channelUpdated = Observable<[void]>();
|
|
@@ -8,7 +8,7 @@ import { Message } from "../codec/MessageCodec.js";
|
|
|
8
8
|
import { MessageExchange } from "./MessageExchange.js";
|
|
9
9
|
|
|
10
10
|
export interface ProtocolHandler {
|
|
11
|
-
|
|
11
|
+
readonly id: number;
|
|
12
12
|
onNewExchange(exchange: MessageExchange, message: Message): Promise<void>;
|
|
13
13
|
close(): Promise<void>;
|
|
14
14
|
}
|
|
@@ -43,6 +43,10 @@ export class SecureChannelMessenger {
|
|
|
43
43
|
this.#defaultExpectedProcessingTimeMs = defaultExpectedProcessingTimeMs;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
get channel() {
|
|
47
|
+
return this.exchange.channel;
|
|
48
|
+
}
|
|
49
|
+
|
|
46
50
|
async nextMessage(
|
|
47
51
|
expectedMessageType: number,
|
|
48
52
|
expectedProcessingTimeMs = this.#defaultExpectedProcessingTimeMs,
|
|
@@ -28,9 +28,7 @@ import { TlvSecureChannelStatusMessage } from "./SecureChannelStatusMessageSchem
|
|
|
28
28
|
const logger = Logger.get("SecureChannelProtocol");
|
|
29
29
|
|
|
30
30
|
export class StatusReportOnlySecureChannelProtocol implements ProtocolHandler {
|
|
31
|
-
|
|
32
|
-
return SECURE_CHANNEL_PROTOCOL_ID;
|
|
33
|
-
}
|
|
31
|
+
readonly id = SECURE_CHANNEL_PROTOCOL_ID;
|
|
34
32
|
|
|
35
33
|
async onNewExchange(exchange: MessageExchange, message: Message) {
|
|
36
34
|
const messageType = message.payloadHeader.messageType;
|
|
@@ -292,11 +292,12 @@ export class SecureSession extends Session {
|
|
|
292
292
|
return this.#fabric;
|
|
293
293
|
}
|
|
294
294
|
|
|
295
|
-
async clearSubscriptions(flushSubscriptions = false) {
|
|
295
|
+
async clearSubscriptions(flushSubscriptions = false, cancelledByPeer = false) {
|
|
296
296
|
const subscriptions = [...this.#subscriptions]; // get all values because subscriptions will remove themselves when cancelled
|
|
297
297
|
for (const subscription of subscriptions) {
|
|
298
|
-
await subscription.close(flushSubscriptions);
|
|
298
|
+
await subscription.close(flushSubscriptions, cancelledByPeer);
|
|
299
299
|
}
|
|
300
|
+
return subscriptions.length;
|
|
300
301
|
}
|
|
301
302
|
|
|
302
303
|
/** Ends a session. Outstanding subscription data will be flushed before the session is destroyed. */
|
package/src/session/Session.ts
CHANGED
|
@@ -62,6 +62,7 @@ export abstract class Session {
|
|
|
62
62
|
abstract get closingAfterExchangeFinished(): boolean;
|
|
63
63
|
#manager?: SessionManager;
|
|
64
64
|
timestamp = Time.nowMs();
|
|
65
|
+
readonly createdAt = Time.nowMs();
|
|
65
66
|
activeTimestamp = 0;
|
|
66
67
|
protected readonly idleIntervalMs: number;
|
|
67
68
|
protected readonly activeIntervalMs: number;
|
|
@@ -378,14 +378,16 @@ export class SessionManager {
|
|
|
378
378
|
});
|
|
379
379
|
}
|
|
380
380
|
|
|
381
|
-
async removeAllSessionsForNode(address: PeerAddress, sendClose = false) {
|
|
381
|
+
async removeAllSessionsForNode(address: PeerAddress, sendClose = false, closeBeforeCreatedTimestamp?: number) {
|
|
382
382
|
await this.#construction;
|
|
383
383
|
|
|
384
384
|
for (const session of this.#sessions) {
|
|
385
385
|
if (!session.isSecure) continue;
|
|
386
|
+
if (closeBeforeCreatedTimestamp !== undefined && session.createdAt >= closeBeforeCreatedTimestamp) continue;
|
|
386
387
|
const secureSession = session;
|
|
387
388
|
if (secureSession.peerIs(address)) {
|
|
388
389
|
await secureSession.destroy(sendClose, false);
|
|
390
|
+
this.#sessions.delete(session);
|
|
389
391
|
}
|
|
390
392
|
}
|
|
391
393
|
}
|
|
@@ -563,17 +565,12 @@ export class SessionManager {
|
|
|
563
565
|
}
|
|
564
566
|
|
|
565
567
|
/** Clears all subscriptions for a given node and returns how many were cleared. */
|
|
566
|
-
async clearSubscriptionsForNode(
|
|
568
|
+
async clearSubscriptionsForNode(peerAddress: PeerAddress, flushSubscriptions?: boolean) {
|
|
567
569
|
let clearedCount = 0;
|
|
568
570
|
for (const session of this.#sessions) {
|
|
569
|
-
if (session.
|
|
570
|
-
|
|
571
|
+
if (PeerAddress.is(session.peerAddress, peerAddress)) {
|
|
572
|
+
clearedCount += await session.clearSubscriptions(flushSubscriptions, true);
|
|
571
573
|
}
|
|
572
|
-
if (session.peerNodeId !== nodeId) {
|
|
573
|
-
continue;
|
|
574
|
-
}
|
|
575
|
-
await session.clearSubscriptions(flushSubscriptions);
|
|
576
|
-
clearedCount++;
|
|
577
574
|
}
|
|
578
575
|
return clearedCount;
|
|
579
576
|
}
|
|
@@ -30,6 +30,8 @@ import { CaseServerMessenger } from "./CaseMessenger.js";
|
|
|
30
30
|
const logger = Logger.get("CaseServer");
|
|
31
31
|
|
|
32
32
|
export class CaseServer implements ProtocolHandler {
|
|
33
|
+
readonly id = SECURE_CHANNEL_PROTOCOL_ID;
|
|
34
|
+
|
|
33
35
|
#sessions: SessionManager;
|
|
34
36
|
#fabrics: FabricManager;
|
|
35
37
|
|
|
@@ -58,10 +60,6 @@ export class CaseServer implements ProtocolHandler {
|
|
|
58
60
|
}
|
|
59
61
|
}
|
|
60
62
|
|
|
61
|
-
getId(): number {
|
|
62
|
-
return SECURE_CHANNEL_PROTOCOL_ID;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
63
|
private async handleSigma1(messenger: CaseServerMessenger) {
|
|
66
64
|
logger.info(`Received pairing request from ${messenger.getChannelName()}`);
|
|
67
65
|
// Generate pairing info
|