feat(jitsi): add SCTP fallback when colibri-ws is unavailable

- Fixed instances that were not working x3
This commit is contained in:
zarazaex69
2026-05-25 10:41:23 +03:00
parent bcc3dd7ee7
commit c2170c058b
3 changed files with 31 additions and 7 deletions

2
go.mod
View File

@@ -15,7 +15,7 @@ require (
github.com/xtaci/kcp-go/v5 v5.6.72 github.com/xtaci/kcp-go/v5 v5.6.72
github.com/xtaci/smux v1.5.57 github.com/xtaci/smux v1.5.57
github.com/zarazaex69/gr v0.1.4 github.com/zarazaex69/gr v0.1.4
github.com/zarazaex69/j v0.0.0-20260525072612-27cb999da9fc github.com/zarazaex69/j v0.0.0-20260525073820-97bd0a207728
golang.org/x/crypto v0.52.0 golang.org/x/crypto v0.52.0
golang.org/x/mobile v0.0.0-20260520154334-0e4426e1883d golang.org/x/mobile v0.0.0-20260520154334-0e4426e1883d
golang.org/x/sys v0.45.0 golang.org/x/sys v0.45.0

2
go.sum
View File

@@ -237,6 +237,8 @@ github.com/zarazaex69/j v0.0.0-20260525070842-7db7b32d7255 h1:SGRiNJpCvIHUrAQxPK
github.com/zarazaex69/j v0.0.0-20260525070842-7db7b32d7255/go.mod h1:7/ypJTenOIPx23fpo5uF7l4u+rxZqg9cFbTL/N77Ktc= github.com/zarazaex69/j v0.0.0-20260525070842-7db7b32d7255/go.mod h1:7/ypJTenOIPx23fpo5uF7l4u+rxZqg9cFbTL/N77Ktc=
github.com/zarazaex69/j v0.0.0-20260525072612-27cb999da9fc h1:LQ9YzrfcuXf4BHAgotAKBQtmW3eCegs60+YcKON9gr4= github.com/zarazaex69/j v0.0.0-20260525072612-27cb999da9fc h1:LQ9YzrfcuXf4BHAgotAKBQtmW3eCegs60+YcKON9gr4=
github.com/zarazaex69/j v0.0.0-20260525072612-27cb999da9fc/go.mod h1:7/ypJTenOIPx23fpo5uF7l4u+rxZqg9cFbTL/N77Ktc= github.com/zarazaex69/j v0.0.0-20260525072612-27cb999da9fc/go.mod h1:7/ypJTenOIPx23fpo5uF7l4u+rxZqg9cFbTL/N77Ktc=
github.com/zarazaex69/j v0.0.0-20260525073820-97bd0a207728 h1:KC1+P2RytHIjaEPbqdCRF3C142Edj2KJj/1O0t57pV8=
github.com/zarazaex69/j v0.0.0-20260525073820-97bd0a207728/go.mod h1:7/ypJTenOIPx23fpo5uF7l4u+rxZqg9cFbTL/N77Ktc=
github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ=
github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs=

View File

@@ -302,7 +302,10 @@ func (s *Session) joinAndOpenBridge(ctx context.Context) (*j.Session, error) {
} }
logger.Infof("jitsi: joined %s/%s; colibri-ws=%s", s.host, s.room, jSess.ColibriWS) logger.Infof("jitsi: joined %s/%s; colibri-ws=%s", s.host, s.room, jSess.ColibriWS)
if s.onData != nil || s.onPeerData != nil { needBridge := s.onData != nil || s.onPeerData != nil
sctpBridge := needBridge && jSess.ColibriWS == ""
if needBridge && jSess.ColibriWS != "" {
bctx, bcancel := context.WithTimeout(ctx, bridgeOpenTimeout) bctx, bcancel := context.WithTimeout(ctx, bridgeOpenTimeout)
err := jSess.OpenBridge(bctx) err := jSess.OpenBridge(bctx)
bcancel() bcancel()
@@ -310,21 +313,33 @@ func (s *Session) joinAndOpenBridge(ctx context.Context) (*j.Session, error) {
_ = jSess.Close() _ = jSess.Close()
return nil, fmt.Errorf("open bridge: %w", err) return nil, fmt.Errorf("open bridge: %w", err)
} }
// Re-latch peer on every bridge open: after a reconnect the partner's
// MUC nick may have changed.
s.peerEndpoint.Store(nil) s.peerEndpoint.Store(nil)
s.peerVideoSSRC.Store(0) s.peerVideoSSRC.Store(0)
s.bridgeReady.Store(true) s.bridgeReady.Store(true)
logger.Infof("jitsi: bridge open (endpoints=%v)", jSess.Endpoints()) logger.Infof("jitsi: bridge open colibri-ws (endpoints=%v)", jSess.Endpoints())
} }
if s.shouldNegotiatePC() { if s.shouldNegotiatePC() {
if err := s.negotiatePC(ctx, jSess); err != nil { if err := s.negotiatePC(ctx, jSess, sctpBridge); err != nil {
_ = jSess.Close() _ = jSess.Close()
return nil, err return nil, err
} }
} }
if sctpBridge {
bctx, bcancel := context.WithTimeout(ctx, bridgeOpenTimeout)
err := jSess.WaitBridgeSCTP(bctx)
bcancel()
if err != nil {
_ = jSess.Close()
return nil, fmt.Errorf("open bridge sctp: %w", err)
}
s.peerEndpoint.Store(nil)
s.peerVideoSSRC.Store(0)
s.bridgeReady.Store(true)
logger.Infof("jitsi: bridge open sctp (endpoints=%v)", jSess.Endpoints())
}
return jSess, nil return jSess, nil
} }
@@ -370,7 +385,7 @@ func (s *Session) videoTrackHandler() func(*webrtc.TrackRemote, *webrtc.RTPRecei
// would obscure the wire order rather than clarify it. // would obscure the wire order rather than clarify it.
// //
//nolint:cyclop // sequential Jingle negotiation steps; refactoring would hide ordering //nolint:cyclop // sequential Jingle negotiation steps; refactoring would hide ordering
func (s *Session) negotiatePC(ctx context.Context, jSess *j.Session) error { func (s *Session) negotiatePC(ctx context.Context, jSess *j.Session, sctpBridge bool) error {
settings := webrtc.SettingEngine{} settings := webrtc.SettingEngine{}
settings.LoggerFactory = logger.NewPionLoggerFactory() settings.LoggerFactory = logger.NewPionLoggerFactory()
@@ -480,6 +495,13 @@ func (s *Session) negotiatePC(ctx context.Context, jSess *j.Session) error {
s.wg.Add(1) s.wg.Add(1)
go s.trickleDrainLoop(pc, neg, jSess.LowLevel().Stanzas()) go s.trickleDrainLoop(pc, neg, jSess.LowLevel().Stanzas())
if sctpBridge {
if err := jSess.PrepareBridgeSCTP(pc); err != nil {
_ = pc.Close()
return fmt.Errorf("prepare bridge sctp: %w", err)
}
}
if err := neg.Accept(ctx); err != nil { if err := neg.Accept(ctx); err != nil {
_ = pc.Close() _ = pc.Close()
return fmt.Errorf("session-accept: %w", err) return fmt.Errorf("session-accept: %w", err)