@@ -28,6 +28,7 @@ import {
2828 UserPacket ,
2929 protoInt64 ,
3030} from '@livekit/protocol' ;
31+ import { SignalConnectionState } from '../../api/SignalClient' ;
3132import type { InternalRoomOptions } from '../../options' ;
3233import { PCTransportState } from '../PCTransportManager' ;
3334import type RTCEngine from '../RTCEngine' ;
@@ -866,7 +867,37 @@ export default class LocalParticipant extends Participant {
866867 if ( opts . source ) {
867868 track . source = opts . source ;
868869 }
869- const publishPromise = this . publish ( track , opts , isStereo ) ;
870+ const publishPromise = new Promise < LocalTrackPublication > ( async ( resolve , reject ) => {
871+ try {
872+ if ( this . engine . client . currentState !== SignalConnectionState . CONNECTED ) {
873+ this . log . debug ( 'deferring track publication until signal is connected' , {
874+ ...this . logContext ,
875+ track : getLogContextFromTrack ( track ) ,
876+ } ) ;
877+ const onSignalConnected = async ( ) => {
878+ return this . publish ( track , opts , isStereo ) . then ( resolve ) . catch ( reject ) ;
879+ } ;
880+ setTimeout ( ( ) => {
881+ this . engine . off ( EngineEvent . SignalConnected , onSignalConnected ) ;
882+ reject (
883+ new PublishTrackError (
884+ 'publishing rejected as engine not connected within timeout' ,
885+ 408 ,
886+ ) ,
887+ ) ;
888+ } , 15_000 ) ;
889+ this . engine . once ( EngineEvent . SignalConnected , onSignalConnected ) ;
890+ this . engine . on ( EngineEvent . Closing , ( ) => {
891+ this . engine . off ( EngineEvent . SignalConnected , onSignalConnected ) ;
892+ reject ( new PublishTrackError ( 'publishing rejected as engine closed' , 499 ) ) ;
893+ } ) ;
894+ } else {
895+ return await this . publish ( track , opts , isStereo ) ;
896+ }
897+ } catch ( e ) {
898+ reject ( e ) ;
899+ }
900+ } ) ;
870901 this . pendingPublishPromises . set ( track , publishPromise ) ;
871902 try {
872903 const publication = await publishPromise ;
0 commit comments