feat(sse): per-connection filtering with user and workstation context
- Extend sseClient with userID, workstationID, and item filter set - Update Subscribe() to accept userID and workstationID params - Add WatchItem/UnwatchItem/IsWatchingItem methods on sseClient - Add PublishToItem, PublishToWorkstation, PublishToUser targeted delivery - Targeted events get IDs but skip history ring buffer (real-time only) - Update HandleEvents to pass auth user ID and workstation_id query param - Touch workstation last_seen on SSE connect - Existing Publish() broadcast unchanged; all current callers unaffected - Add 5 new tests for targeted delivery and item watch lifecycle Closes #162
This commit is contained in:
@@ -5,6 +5,8 @@ import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/kindredsystems/silo/internal/auth"
|
||||
)
|
||||
|
||||
// HandleEvents serves the SSE event stream.
|
||||
@@ -31,9 +33,19 @@ func (s *Server) HandleEvents(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Connection", "keep-alive")
|
||||
w.Header().Set("X-Accel-Buffering", "no") // nginx: disable proxy buffering
|
||||
|
||||
client := s.broker.Subscribe()
|
||||
userID := ""
|
||||
if user := auth.UserFromContext(r.Context()); user != nil {
|
||||
userID = user.ID
|
||||
}
|
||||
wsID := r.URL.Query().Get("workstation_id")
|
||||
|
||||
client := s.broker.Subscribe(userID, wsID)
|
||||
defer s.broker.Unsubscribe(client)
|
||||
|
||||
if wsID != "" {
|
||||
s.workstations.Touch(r.Context(), wsID)
|
||||
}
|
||||
|
||||
// Replay missed events if Last-Event-ID is present.
|
||||
if lastIDStr := r.Header.Get("Last-Event-ID"); lastIDStr != "" {
|
||||
if lastID, err := strconv.ParseUint(lastIDStr, 10, 64); err == nil {
|
||||
|
||||
Reference in New Issue
Block a user