diff --git a/internal/engine/jitsi/jitsi.go b/internal/engine/jitsi/jitsi.go
index 31c6d70..3336dae 100644
--- a/internal/engine/jitsi/jitsi.go
+++ b/internal/engine/jitsi/jitsi.go
@@ -1329,19 +1329,37 @@ func (s *Session) reconnect(ctx context.Context) error {
s.resetPeerEpochs()
s.drainSendQueue()
- jSess := s.jSess.Load()
- if jSess == nil {
- return s.reconnectFull(ctx)
+ // Re-establish the XMPP/MUC session from scratch rather than reusing the
+ // lightweight jSess.Rejoin (leave+join) path. Rejoin skips the Jicofo
+ // focus-allocation IQ, and Jitsi gates the MUC on focus: once the server
+ // is left alone in the room, Jicofo idle-terminates the conference
+ // (session-terminate ) and tears down the room, after which a
+ // bare presence is rejected with .
+ // The library's JoinMUC then matches a stale status-110 still buffered in
+ // its stanza channel and falsely reports success, so we wait forever for a
+ // session-initiate that never comes while actually being outside the room.
+ //
+ // j.JoinMUC re-runs dial -> focus allocation -> MUC join in the correct
+ // order (focus first, so Jicofo recreates the room), exactly like the
+ // initial Connect, but WITHOUT blocking on session-initiate — preserving
+ // the non-blocking reconnect contract. We wait for the fresh
+ // session-initiate separately via WaitJingleReinitiate once a peer rejoins.
+ if old := s.jSess.Swap(nil); old != nil {
+ _ = old.Close()
}
- // Rejoin MUC (leave + join) without waiting for session-initiate.
- // This resets Jicofo's state for our participant so it will send
- // a fresh session-initiate when another peer arrives.
logger.Infof("jitsi: rejoin %s/%s (non-blocking) ...", s.host, s.room)
- if err := jSess.Rejoin(ctx, s.name); err != nil {
+ jSess, err := j.JoinMUC(ctx, j.Config{
+ Host: s.host,
+ Room: s.room,
+ Nick: s.name,
+ Debug: logger.IsVerbose(),
+ })
+ if err != nil {
logger.Warnf("jitsi: rejoin failed: %v - full reconnect", err)
return s.reconnectFull(ctx)
}
+ s.jSess.Store(jSess)
// Wait for Jicofo to send session-initiate (when a peer joins the room).
logger.Infof("jitsi: waiting for session-initiate in %s/%s ...", s.host, s.room)