@@ -43,7 +43,8 @@ type ClientImpl struct {
4343 IsDone bool
4444 DoneReason string
4545 DoneCh chan struct {}
46- SSEventCh chan ssEvent
46+ SSEChannels map [string ]chan ssEvent // map of connectionId to SSE channel
47+ SSEChannelsLock * sync.Mutex
4748 GlobalEventHandler func (event vdom.VDomEvent )
4849 UrlHandlerMux * http.ServeMux
4950 SetupFn func ()
@@ -62,12 +63,13 @@ type ClientImpl struct {
6263
6364func makeClient () * ClientImpl {
6465 client := & ClientImpl {
65- Lock : & sync.Mutex {},
66- DoneCh : make (chan struct {}),
67- SSEventCh : make (chan ssEvent , 100 ),
68- UrlHandlerMux : http .NewServeMux (),
69- ServerId : uuid .New ().String (),
70- RootElem : vdom .H (DefaultComponentName , nil ),
66+ Lock : & sync.Mutex {},
67+ DoneCh : make (chan struct {}),
68+ SSEChannels : make (map [string ]chan ssEvent ),
69+ SSEChannelsLock : & sync.Mutex {},
70+ UrlHandlerMux : http .NewServeMux (),
71+ ServerId : uuid .New ().String (),
72+ RootElem : vdom .H (DefaultComponentName , nil ),
7173 }
7274 client .Root = MakeRoot (client )
7375 return client
@@ -214,18 +216,49 @@ func (c *ClientImpl) listenAndServe(ctx context.Context) error {
214216 return nil
215217}
216218
217- func (c * ClientImpl ) SendAsyncInitiation () error {
218- log .Printf ("send async initiation\n " )
219+ func (c * ClientImpl ) RegisterSSEChannel (connectionId string ) chan ssEvent {
220+ c .SSEChannelsLock .Lock ()
221+ defer c .SSEChannelsLock .Unlock ()
222+
223+ ch := make (chan ssEvent , 100 )
224+ c .SSEChannels [connectionId ] = ch
225+ return ch
226+ }
227+
228+ func (c * ClientImpl ) UnregisterSSEChannel (connectionId string ) {
229+ c .SSEChannelsLock .Lock ()
230+ defer c .SSEChannelsLock .Unlock ()
231+
232+ if ch , exists := c .SSEChannels [connectionId ]; exists {
233+ close (ch )
234+ delete (c .SSEChannels , connectionId )
235+ }
236+ }
237+
238+ func (c * ClientImpl ) SendSSEvent (event ssEvent ) error {
219239 if c .GetIsDone () {
220240 return fmt .Errorf ("client is done" )
221241 }
222242
223- select {
224- case c .SSEventCh <- ssEvent {Event : "asyncinitiation" , Data : nil }:
225- return nil
226- default :
227- return fmt .Errorf ("SSEvent channel is full" )
243+ c .SSEChannelsLock .Lock ()
244+ defer c .SSEChannelsLock .Unlock ()
245+
246+ // Send to all registered SSE channels
247+ for connectionId , ch := range c .SSEChannels {
248+ select {
249+ case ch <- event :
250+ // Successfully sent
251+ default :
252+ log .Printf ("SSEvent channel is full for connection %s, skipping event" , connectionId )
253+ }
228254 }
255+
256+ return nil
257+ }
258+
259+ func (c * ClientImpl ) SendAsyncInitiation () error {
260+ log .Printf ("send async initiation\n " )
261+ return c .SendSSEvent (ssEvent {Event : "asyncinitiation" , Data : nil })
229262}
230263
231264func makeNullRendered () * rpctypes.RenderedElem {
0 commit comments