sync: phase 1 backend + frontend from server
This commit is contained in:
@@ -281,6 +281,46 @@ func (h *Hub) BroadcastToServer(serverID string, event Event) {
|
||||
}
|
||||
}
|
||||
|
||||
// BroadcastToConversation sends an event to all clients who are members of a
|
||||
// given direct-message conversation.
|
||||
func (h *Hub) BroadcastToConversation(convID string, event Event) {
|
||||
data, err := json.Marshal(event)
|
||||
if err != nil {
|
||||
h.logger.Error("failed to marshal event", "type", event.Type, "error", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
rows, err := h.db.QueryContext(ctx, `SELECT user_id FROM conversation_members WHERE conversation_id = $1`, convID)
|
||||
if err != nil {
|
||||
h.logger.Error("failed to load conversation members", "conversation_id", convID, "error", err)
|
||||
return
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
members := make(map[string]struct{})
|
||||
for rows.Next() {
|
||||
var uid string
|
||||
if err := rows.Scan(&uid); err == nil {
|
||||
members[uid] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
h.mu.RLock()
|
||||
defer h.mu.RUnlock()
|
||||
for client := range h.clients {
|
||||
if _, ok := members[client.UserID]; ok {
|
||||
select {
|
||||
case client.send <- data:
|
||||
default:
|
||||
go func(c *Client) { h.unregister <- c }(client)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ServerIDForChannel looks up the server_id that owns the given channel.
|
||||
// Used by handlers to route events to the correct server scope.
|
||||
func (h *Hub) ServerIDForChannel(ctx context.Context, channelID string) (string, error) {
|
||||
|
||||
Reference in New Issue
Block a user