@@ -13,6 +13,7 @@ import (
13
13
"fmt"
14
14
"iter"
15
15
"log"
16
+ "maps"
16
17
"net/url"
17
18
"path/filepath"
18
19
"slices"
@@ -43,7 +44,7 @@ type Server struct {
43
44
sessions []* ServerSession
44
45
sendingMethodHandler_ MethodHandler [* ServerSession ]
45
46
receivingMethodHandler_ MethodHandler [* ServerSession ]
46
- resourceSubscriptions map [string ][] * ServerSession // uri -> session
47
+ resourceSubscriptions map [string ]map [ string ] bool // uri -> session ID -> bool
47
48
}
48
49
49
50
// ServerOptions is used to configure behavior of the server.
@@ -109,7 +110,7 @@ func NewServer(impl *Implementation, opts *ServerOptions) *Server {
109
110
resourceTemplates : newFeatureSet (func (t * serverResourceTemplate ) string { return t .resourceTemplate .URITemplate }),
110
111
sendingMethodHandler_ : defaultSendingMethodHandler [* ServerSession ],
111
112
receivingMethodHandler_ : defaultReceivingMethodHandler [* ServerSession ],
112
- resourceSubscriptions : make (map [string ][] * ServerSession ),
113
+ resourceSubscriptions : make (map [string ]map [ string ] bool ),
113
114
}
114
115
}
115
116
@@ -236,12 +237,9 @@ func (s *Server) capabilities() *serverCapabilities {
236
237
}
237
238
if s .resources .len () > 0 || s .resourceTemplates .len () > 0 {
238
239
caps .Resources = & resourceCapabilities {ListChanged : true }
239
- }
240
- if s .opts .SubscribeHandler != nil {
241
- if caps .Resources == nil {
242
- caps .Resources = & resourceCapabilities {}
240
+ if s .opts .SubscribeHandler != nil {
241
+ caps .Resources .Subscribe = true
243
242
}
244
- caps .Resources .Subscribe = true
245
243
}
246
244
return caps
247
245
}
@@ -447,11 +445,22 @@ func fileResourceHandler(dir string) ResourceHandler {
447
445
448
446
func (s * Server ) ResourceUpdated (ctx context.Context , params * ResourceUpdatedNotificationParams ) error {
449
447
s .mu .Lock ()
450
- sessions := slices .Clone (s .resourceSubscriptions [params .URI ])
448
+ subscribedSessionIDs := maps .Clone (s .resourceSubscriptions [params .URI ])
451
449
s .mu .Unlock ()
452
- if len (sessions ) == 0 {
450
+ if len (subscribedSessionIDs ) == 0 {
453
451
return nil
454
452
}
453
+ sessions := make ([]* ServerSession , 0 , len (subscribedSessionIDs ))
454
+ for sessionID , active := range subscribedSessionIDs {
455
+ if ! active {
456
+ continue
457
+ }
458
+ for session := range s .Sessions () {
459
+ if session .ID () == sessionID {
460
+ sessions = append (sessions , session )
461
+ }
462
+ }
463
+ }
455
464
notifySessions (sessions , notificationResourceUpdated , params )
456
465
return nil
457
466
}
@@ -466,10 +475,10 @@ func (s *Server) subscribe(ctx context.Context, ss *ServerSession, params *Subsc
466
475
s .mu .Lock ()
467
476
defer s .mu .Unlock ()
468
477
uri := params .URI
469
- subscribers := s .resourceSubscriptions [uri ]
470
- if ! slices .Contains (subscribers , ss ) {
471
- s .resourceSubscriptions [uri ] = append (subscribers , ss )
478
+ if s .resourceSubscriptions [uri ] == nil {
479
+ s .resourceSubscriptions [uri ] = make (map [string ]bool )
472
480
}
481
+ s .resourceSubscriptions [uri ][ss .ID ()] = true
473
482
return & emptyResult {}, nil
474
483
}
475
484
@@ -486,10 +495,8 @@ func (s *Server) unsubscribe(ctx context.Context, ss *ServerSession, params *Uns
486
495
defer s .mu .Unlock ()
487
496
488
497
uri := params .URI
489
- if sessions , ok := s .resourceSubscriptions [uri ]; ok {
490
- s .resourceSubscriptions [uri ] = slices .DeleteFunc (sessions , func (s * ServerSession ) bool {
491
- return s == ss
492
- })
498
+ if subscribedSessionIDs , ok := s .resourceSubscriptions [uri ]; ok {
499
+ subscribedSessionIDs [ss .ID ()] = false
493
500
}
494
501
return & emptyResult {}, nil
495
502
}
@@ -541,10 +548,9 @@ func (s *Server) disconnect(cc *ServerSession) {
541
548
s .sessions = slices .DeleteFunc (s .sessions , func (cc2 * ServerSession ) bool {
542
549
return cc2 == cc
543
550
})
544
- for uri , sessions := range s .resourceSubscriptions {
545
- s .resourceSubscriptions [uri ] = slices .DeleteFunc (sessions , func (cc2 * ServerSession ) bool {
546
- return cc2 == cc
547
- })
551
+
552
+ for _ , subscribedSessionIDs := range s .resourceSubscriptions {
553
+ delete (subscribedSessionIDs , cc .ID ())
548
554
}
549
555
}
550
556
0 commit comments