fix: presence unreliable within same pod
It was broadcasting presence changes to other pods, but not notifying clients connected to the same pod
This commit is contained in:
@@ -101,6 +101,9 @@ func (h *Hub) handleSubscribe(ctx context.Context, req *subscribeRequest) {
|
||||
h.channels[req.channelID] = ch
|
||||
}
|
||||
|
||||
// Capture before addMember so multi-tab joins don't emit a spurious join.
|
||||
wasPresentLocally := ch.hasHumanID(req.conn.humanID)
|
||||
|
||||
// Add to local channel
|
||||
ch.addMember(req.conn, req.conn.humanID)
|
||||
|
||||
@@ -124,6 +127,16 @@ func (h *Hub) handleSubscribe(ctx context.Context, req *subscribeRequest) {
|
||||
Channel: req.channelID,
|
||||
Presence: presence,
|
||||
})
|
||||
|
||||
// Notify other local members. The Redis self-filter drops our own echo,
|
||||
// so same-pod peers would otherwise never hear about this join.
|
||||
if !wasPresentLocally {
|
||||
ch.broadcast(ServerMessage{
|
||||
Type: TypeJoin,
|
||||
Channel: req.channelID,
|
||||
HumanID: req.conn.humanID,
|
||||
}, req.conn)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Hub) handleUnsubscribe(ctx context.Context, req *unsubscribeRequest) {
|
||||
@@ -144,6 +157,16 @@ func (h *Hub) handleUnsubscribe(ctx context.Context, req *unsubscribeRequest) {
|
||||
slog.Error("redis unsubscribe failed", "channelId", req.channelID, "error", err)
|
||||
}
|
||||
|
||||
// Notify other local members iff the humanID is fully gone from this pod
|
||||
// (multi-tab: other conns keep them present, so no leave fires).
|
||||
if !ch.hasHumanID(req.conn.humanID) {
|
||||
ch.broadcast(ServerMessage{
|
||||
Type: TypeLeave,
|
||||
Channel: req.channelID,
|
||||
HumanID: req.conn.humanID,
|
||||
}, req.conn)
|
||||
}
|
||||
|
||||
// Clean up empty local channel
|
||||
if ch.isEmpty() {
|
||||
delete(h.channels, req.channelID)
|
||||
@@ -192,6 +215,14 @@ func (h *Hub) handleDisconnect(ctx context.Context, conn *Conn) {
|
||||
slog.Error("redis unsubscribe on disconnect failed", "channelId", channelID, "error", err)
|
||||
}
|
||||
|
||||
if !ch.hasHumanID(conn.humanID) {
|
||||
ch.broadcast(ServerMessage{
|
||||
Type: TypeLeave,
|
||||
Channel: channelID,
|
||||
HumanID: conn.humanID,
|
||||
}, conn)
|
||||
}
|
||||
|
||||
if ch.isEmpty() {
|
||||
delete(h.channels, channelID)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user