@@ -4,6 +4,7 @@ import 'dart:io';
44
55import 'package:collection/collection.dart' ;
66import 'package:flutter_webrtc/flutter_webrtc.dart' as rtc;
7+ import 'package:rxdart/rxdart.dart' ;
78import 'package:webrtc_interface/webrtc_interface.dart' ;
89
910import '../../../protobuf/video/sfu/event/events.pb.dart' as sfu_events;
@@ -82,7 +83,9 @@ class CallSession extends Disposable {
8283 final OnFullReconnectNeeded onFullReconnectNeeded;
8384
8485 RtcManager ? rtcManager;
85- StreamSubscription <SfuEvent >? eventsSubscription;
86+
87+ BehaviorSubject <RtcManager >? _rtcManagerSubject;
88+ StreamSubscription <SfuEvent >? _eventsSubscription;
8689 StreamSubscription <Map <String , dynamic >>? _statsSubscription;
8790 Timer ? _peerConnectionCheckTimer;
8891
@@ -106,8 +109,25 @@ class CallSession extends Disposable {
106109 Future <Result <None >> start () async {
107110 try {
108111 _logger.d (() => '[start] no args' );
109- await eventsSubscription? .cancel ();
110- eventsSubscription = sfuWS.events.listen (_onSfuEvent);
112+
113+ await _eventsSubscription? .cancel ();
114+ await _rtcManagerSubject? .close ();
115+
116+ _rtcManagerSubject = BehaviorSubject ();
117+
118+ // Buffer sfu events until rtc manager is set
119+ final bufferedStream =
120+ sfuWS.events.asStream ().buffer (_rtcManagerSubject! );
121+
122+ // Handle buffered events and then listen to sfu events as normal
123+ _eventsSubscription = bufferedStream.asyncExpand ((bufferedEvents) async * {
124+ for (final event in bufferedEvents) {
125+ await _onSfuEvent (event);
126+ }
127+
128+ yield * sfuWS.events.asStream ();
129+ }).listen (_onSfuEvent);
130+
111131 final wsResult = await sfuWS.connect ();
112132 if (wsResult.isFailure) {
113133 _logger.e (() => '[start] ws connect failed: $wsResult ' );
@@ -150,6 +170,8 @@ class CallSession extends Disposable {
150170 ..onRemoteTrackReceived = _onRemoteTrackReceived
151171 ..onStatsReceived = _onStatsReceived;
152172
173+ _rtcManagerSubject! .add (rtcManager! );
174+
153175 await _statsSubscription? .cancel ();
154176 _statsSubscription = rtcManager? .statsStream.listen ((rawStats) {
155177 sfuClient.sendStats (
@@ -183,8 +205,8 @@ class CallSession extends Disposable {
183205 final genericSdp = await RtcManager .getGenericSdp ();
184206 _logger.v (() => '[fastReconnect] genericSdp.len: ${genericSdp .length }' );
185207
186- await eventsSubscription ? .cancel ();
187- eventsSubscription = sfuWS.events.listen (_onSfuEvent);
208+ await _eventsSubscription ? .cancel ();
209+ _eventsSubscription = sfuWS.events.listen (_onSfuEvent);
188210 await sfuWS.connect ();
189211
190212 sfuWS.send (
@@ -234,8 +256,8 @@ class CallSession extends Disposable {
234256 _logger.d (() => '[dispose] no args' );
235257 await _stats.close ();
236258 await _saBuffer.cancel ();
237- await eventsSubscription ? .cancel ();
238- eventsSubscription = null ;
259+ await _eventsSubscription ? .cancel ();
260+ _eventsSubscription = null ;
239261 await _statsSubscription? .cancel ();
240262 _statsSubscription = null ;
241263 await sfuWS.disconnect ();
@@ -395,6 +417,7 @@ class CallSession extends Disposable {
395417 Future <void > _onSubscriberOffer (SfuSubscriberOfferEvent event) async {
396418 final offerSdp = event.sdp;
397419 _logger.i (() => '[onSubscriberOffer] event: $event ' );
420+
398421 final answerSdp = await rtcManager? .onSubscriberOffer (offerSdp);
399422 if (answerSdp == null ) {
400423 _logger.w (() => '[onSubscriberOffer] rejected (answerSdp is null)' );
0 commit comments