From ac93e5c0286fbc422a906e57d437bec45e1a049d Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Thu, 16 Dec 2021 21:00:56 -0300 Subject: [PATCH] make subscription ids unique per each websocket connection. before they were globally unique, which was wrong. --- handlers.go | 2 +- listener.go | 33 ++++++++++++++++++++++----------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/handlers.go b/handlers.go index 0fca719..d152989 100644 --- a/handlers.go +++ b/handlers.go @@ -130,7 +130,7 @@ func handleWebsocket(w http.ResponseWriter, r *http.Request) { return } - removeListener(id) + removeListener(conn, id) } }(message) } diff --git a/listener.go b/listener.go index 6c2c4eb..be8dccc 100644 --- a/listener.go +++ b/listener.go @@ -9,11 +9,10 @@ import ( ) type Listener struct { - ws *websocket.Conn filters filter.EventFilters } -var listeners = make(map[string]*Listener) +var listeners = make(map[*websocket.Conn]map[string]*Listener) var listenersMutex = sync.Mutex{} func setListener(id string, conn *websocket.Conn, filters filter.EventFilters) { @@ -22,19 +21,30 @@ func setListener(id string, conn *websocket.Conn, filters filter.EventFilters) { listenersMutex.Unlock() }() - listeners[id] = &Listener{ - ws: conn, + subs, ok := listeners[conn] + if !ok { + subs = make(map[string]*Listener) + listeners[conn] = subs + } + + subs[id] = &Listener{ filters: filters, } } -func removeListener(id string) { +func removeListener(conn *websocket.Conn, id string) { listenersMutex.Lock() defer func() { listenersMutex.Unlock() }() - delete(listeners, id) + subs, ok := listeners[conn] + if ok { + delete(listeners[conn], id) + if len(subs) == 0 { + delete(listeners, conn) + } + } } func notifyListeners(event *event.Event) { @@ -43,11 +53,12 @@ func notifyListeners(event *event.Event) { listenersMutex.Unlock() }() - for id, listener := range listeners { - if !listener.filters.Match(event) { - continue + for conn, subs := range listeners { + for id, listener := range subs { + if !listener.filters.Match(event) { + continue + } + conn.WriteJSON([]interface{}{"EVENT", id, event}) } - - listener.ws.WriteJSON([]interface{}{"EVENT", id, event}) } }