@@ -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.
@@ -108,7 +109,7 @@ func NewServer(impl *Implementation, opts *ServerOptions) *Server {
108
109
resourceTemplates : newFeatureSet (func (t * serverResourceTemplate ) string { return t .resourceTemplate .URITemplate }),
109
110
sendingMethodHandler_ : defaultSendingMethodHandler [* ServerSession ],
110
111
receivingMethodHandler_ : defaultReceivingMethodHandler [* ServerSession ],
111
- resourceSubscriptions : make (map [string ][] * ServerSession ),
112
+ resourceSubscriptions : make (map [string ]map [ string ] bool ),
112
113
}
113
114
}
114
115
@@ -235,12 +236,9 @@ func (s *Server) capabilities() *serverCapabilities {
235
236
}
236
237
if s .resources .len () > 0 || s .resourceTemplates .len () > 0 {
237
238
caps .Resources = & resourceCapabilities {ListChanged : true }
238
- }
239
- if s .opts .SubscribeHandler != nil {
240
- if caps .Resources == nil {
241
- caps .Resources = & resourceCapabilities {}
239
+ if s .opts .SubscribeHandler != nil {
240
+ caps .Resources .Subscribe = true
242
241
}
243
- caps .Resources .Subscribe = true
244
242
}
245
243
return caps
246
244
}
@@ -446,11 +444,22 @@ func fileResourceHandler(dir string) ResourceHandler {
446
444
447
445
func (s * Server ) ResourceUpdated (ctx context.Context , params * ResourceUpdatedNotificationParams ) error {
448
446
s .mu .Lock ()
449
- sessions := slices .Clone (s .resourceSubscriptions [params .URI ])
447
+ subscribedSessionIDs := maps .Clone (s .resourceSubscriptions [params .URI ])
450
448
s .mu .Unlock ()
451
- if len (sessions ) == 0 {
449
+ if len (subscribedSessionIDs ) == 0 {
452
450
return nil
453
451
}
452
+ sessions := make ([]* ServerSession , 0 , len (subscribedSessionIDs ))
453
+ for sessionID , active := range subscribedSessionIDs {
454
+ if ! active {
455
+ continue
456
+ }
457
+ for session := range s .Sessions () {
458
+ if session .ID () == sessionID {
459
+ sessions = append (sessions , session )
460
+ }
461
+ }
462
+ }
454
463
notifySessions (sessions , notificationResourceUpdated , params )
455
464
return nil
456
465
}
@@ -465,10 +474,10 @@ func (s *Server) subscribe(ctx context.Context, ss *ServerSession, params *Subsc
465
474
s .mu .Lock ()
466
475
defer s .mu .Unlock ()
467
476
uri := params .URI
468
- subscribers := s .resourceSubscriptions [uri ]
469
- if ! slices .Contains (subscribers , ss ) {
470
- s .resourceSubscriptions [uri ] = append (subscribers , ss )
477
+ if s .resourceSubscriptions [uri ] == nil {
478
+ s .resourceSubscriptions [uri ] = make (map [string ]bool )
471
479
}
480
+ s .resourceSubscriptions [uri ][ss .ID ()] = true
472
481
return & emptyResult {}, nil
473
482
}
474
483
@@ -485,10 +494,8 @@ func (s *Server) unsubscribe(ctx context.Context, ss *ServerSession, params *Uns
485
494
defer s .mu .Unlock ()
486
495
487
496
uri := params .URI
488
- if sessions , ok := s .resourceSubscriptions [uri ]; ok {
489
- s .resourceSubscriptions [uri ] = slices .DeleteFunc (sessions , func (s * ServerSession ) bool {
490
- return s == ss
491
- })
497
+ if subscribedSessionIDs , ok := s .resourceSubscriptions [uri ]; ok {
498
+ subscribedSessionIDs [ss .ID ()] = false
492
499
}
493
500
return & emptyResult {}, nil
494
501
}
@@ -540,10 +547,9 @@ func (s *Server) disconnect(cc *ServerSession) {
540
547
s .sessions = slices .DeleteFunc (s .sessions , func (cc2 * ServerSession ) bool {
541
548
return cc2 == cc
542
549
})
543
- for uri , sessions := range s .resourceSubscriptions {
544
- s .resourceSubscriptions [uri ] = slices .DeleteFunc (sessions , func (cc2 * ServerSession ) bool {
545
- return cc2 == cc
546
- })
550
+
551
+ for _ , subscribedSessionIDs := range s .resourceSubscriptions {
552
+ delete (subscribedSessionIDs , cc .ID ())
547
553
}
548
554
}
549
555
0 commit comments