@@ -26,6 +26,14 @@ const defaultServerOptions = {
26
26
gcInterval : 3e5
27
27
}
28
28
29
+ /**
30
+ * Rendezvous point contains the connection to a rendezvous server, as well as,
31
+ * the cookies per namespace that the client received.
32
+ * @typedef {Object } RendezvousPoint
33
+ * @property {Connection } connection
34
+ * @property {Map<string, string> } cookies
35
+ */
36
+
29
37
/**
30
38
* Libp2p Rendezvous.
31
39
* A lightweight mechanism for generalized peer discovery.
@@ -57,9 +65,15 @@ class Rendezvous {
57
65
}
58
66
59
67
/**
60
- * @type {Map<string, Connection > }
68
+ * @type {Map<string, RendezvousPoint > }
61
69
*/
62
- this . _rendezvousConns = new Map ( )
70
+ this . _rendezvousPoints = new Map ( )
71
+
72
+ /**
73
+ * Client cookies per namespace for own server
74
+ * @type {Map<string, string> }
75
+ */
76
+ this . _cookiesSelf = new Map ( )
63
77
64
78
this . _server = undefined
65
79
@@ -120,12 +134,19 @@ class Rendezvous {
120
134
}
121
135
122
136
this . _registrarId = undefined
137
+ this . _rendezvousPoints . clear ( )
138
+ this . _cookiesSelf . clear ( )
139
+
123
140
log ( 'stopped' )
124
141
}
125
142
143
+ /**
144
+ * Keep registrations updated on servers.
145
+ * @returns {void }
146
+ */
126
147
_keepRegistrations ( ) {
127
148
const register = ( ) => {
128
- if ( ! this . _rendezvousConns . size ) {
149
+ if ( ! this . _rendezvousPoints . size ) {
129
150
return
130
151
}
131
152
@@ -152,7 +173,7 @@ class Rendezvous {
152
173
const idB58Str = peerId . toB58String ( )
153
174
log ( 'connected' , idB58Str )
154
175
155
- this . _rendezvousConns . set ( idB58Str , conn )
176
+ this . _rendezvousPoints . set ( idB58Str , { connection : conn } )
156
177
}
157
178
158
179
/**
@@ -164,7 +185,7 @@ class Rendezvous {
164
185
const idB58Str = peerId . toB58String ( )
165
186
log ( 'disconnected' , idB58Str )
166
187
167
- this . _rendezvousConns . delete ( idB58Str )
188
+ this . _rendezvousPoints . delete ( idB58Str )
168
189
169
190
if ( this . _server ) {
170
191
this . _server . removePeerRegistrations ( peerId )
@@ -196,7 +217,7 @@ class Rendezvous {
196
217
}
197
218
198
219
// Are there available rendezvous servers?
199
- if ( ! this . _rendezvousConns . size ) {
220
+ if ( ! this . _rendezvousPoints . size ) {
200
221
throw errCode ( new Error ( 'no rendezvous servers connected' ) , errCodes . NO_CONNECTED_RENDEZVOUS_SERVERS )
201
222
}
202
223
@@ -214,8 +235,8 @@ class Rendezvous {
214
235
215
236
const registerTasks = [ ]
216
237
const taskFn = async ( id ) => {
217
- const conn = this . _rendezvousConns . get ( id )
218
- const { stream } = await conn . newStream ( PROTOCOL_MULTICODEC )
238
+ const { connection } = this . _rendezvousPoints . get ( id )
239
+ const { stream } = await connection . newStream ( PROTOCOL_MULTICODEC )
219
240
220
241
const [ response ] = await pipe (
221
242
[ message ] ,
@@ -235,7 +256,7 @@ class Rendezvous {
235
256
return recMessage . registerResponse . ttl
236
257
}
237
258
238
- for ( const id of this . _rendezvousConns . keys ( ) ) {
259
+ for ( const id of this . _rendezvousPoints . keys ( ) ) {
239
260
registerTasks . push ( taskFn ( id ) )
240
261
}
241
262
@@ -255,7 +276,7 @@ class Rendezvous {
255
276
}
256
277
257
278
// Are there available rendezvous servers?
258
- if ( ! this . _rendezvousConns . size ) {
279
+ if ( ! this . _rendezvousPoints . size ) {
259
280
throw errCode ( new Error ( 'no rendezvous servers connected' ) , errCodes . NO_CONNECTED_RENDEZVOUS_SERVERS )
260
281
}
261
282
@@ -269,8 +290,8 @@ class Rendezvous {
269
290
270
291
const unregisterTasks = [ ]
271
292
const taskFn = async ( id ) => {
272
- const conn = this . _rendezvousConns . get ( id )
273
- const { stream } = await conn . newStream ( PROTOCOL_MULTICODEC )
293
+ const { connection } = this . _rendezvousPoints . get ( id )
294
+ const { stream } = await connection . newStream ( PROTOCOL_MULTICODEC )
274
295
275
296
await pipe (
276
297
[ message ] ,
@@ -282,7 +303,7 @@ class Rendezvous {
282
303
)
283
304
}
284
305
285
- for ( const id of this . _rendezvousConns . keys ( ) ) {
306
+ for ( const id of this . _rendezvousPoints . keys ( ) ) {
286
307
unregisterTasks . push ( taskFn ( id ) )
287
308
}
288
309
@@ -293,12 +314,11 @@ class Rendezvous {
293
314
* Discover peers registered under a given namespace
294
315
* @param {string } ns
295
316
* @param {number } [limit]
296
- * @param {Buffer } [cookie]
297
317
* @returns {AsyncIterable<{ id: PeerId, multiaddrs: Array<Multiaddr>, ns: string, ttl: number }> }
298
318
*/
299
- async * discover ( ns , limit , cookie ) {
319
+ async * discover ( ns , limit ) {
300
320
// Are there available rendezvous servers?
301
- if ( ! this . _rendezvousConns . size ) {
321
+ if ( ! this . _rendezvousPoints . size ) {
302
322
throw errCode ( new Error ( 'no rendezvous servers connected' ) , errCodes . NO_CONNECTED_RENDEZVOUS_SERVERS )
303
323
}
304
324
@@ -311,7 +331,9 @@ class Rendezvous {
311
331
312
332
// Local search if Server
313
333
if ( this . _server ) {
314
- const localRegistrations = this . _server . getRegistrations ( ns , limit )
334
+ const cookieSelf = this . _cookiesSelf . get ( ns )
335
+ const { cookie : cookieS , registrations : localRegistrations } = this . _server . getRegistrations ( ns , { limit, cookie : cookieSelf } )
336
+
315
337
for ( const r of localRegistrations ) {
316
338
yield registrationTransformer ( r )
317
339
@@ -320,21 +342,28 @@ class Rendezvous {
320
342
return
321
343
}
322
344
}
323
- }
324
345
325
- const message = Message . encode ( {
326
- type : MESSAGE_TYPE . DISCOVER ,
327
- discover : {
328
- ns,
329
- limit,
330
- cookie
331
- }
332
- } )
346
+ // Store cookie self
347
+ this . _cookiesSelf . set ( ns , cookieS )
348
+ }
333
349
334
- for ( const id of this . _rendezvousConns . keys ( ) ) {
335
- const conn = this . _rendezvousConns . get ( id )
336
- const { stream } = await conn . newStream ( PROTOCOL_MULTICODEC )
350
+ // Iterate over all rendezvous points
351
+ for ( const [ id , rp ] of this . _rendezvousPoints . entries ( ) ) {
352
+ const rpCookies = rp . cookies || new Map ( )
353
+
354
+ // Check if we have a cookie and encode discover message
355
+ const cookie = rpCookies . get ( ns )
356
+ const message = Message . encode ( {
357
+ type : MESSAGE_TYPE . DISCOVER ,
358
+ discover : {
359
+ ns,
360
+ limit,
361
+ cookie : cookie ? Buffer . from ( cookie ) : undefined
362
+ }
363
+ } )
337
364
365
+ // Send discover message and wait for response
366
+ const { stream } = await rp . connection . newStream ( PROTOCOL_MULTICODEC )
338
367
const [ response ] = await pipe (
339
368
[ message ] ,
340
369
lp . encode ( ) ,
@@ -350,10 +379,18 @@ class Rendezvous {
350
379
throw new Error ( 'unexpected message received' )
351
380
}
352
381
382
+ // Iterate over registrations response
353
383
for ( const r of recMessage . discoverResponse . registrations ) {
354
- // track registrations and check if already provided
384
+ // track registrations
355
385
yield registrationTransformer ( r )
356
386
387
+ // Store cookie
388
+ rpCookies . set ( ns , recMessage . discoverResponse . cookie . toString ( ) )
389
+ this . _rendezvousPoints . set ( id , {
390
+ connection : rp . connection ,
391
+ cookies : rpCookies
392
+ } )
393
+
357
394
limit --
358
395
if ( limit === 0 ) {
359
396
return
0 commit comments