forked from eatvio/eatvio_app
fix(chat): ws manager
This commit is contained in:
@@ -38,6 +38,13 @@ class WsManager {
|
||||
StreamSubscription? _eventSubscription;
|
||||
StreamSubscription? _connectionEstablishedSubscription;
|
||||
|
||||
/// Широковещательный сигнал о восстановлении соединения после обрыва (S5).
|
||||
///
|
||||
/// Контроллер создаётся один раз и не закрывается в [clear]: подписчики
|
||||
/// (чаты, окно чата) переживают логаут/повторный вход и продолжают получать
|
||||
/// сигналы. Если контроллер всё же закрыт, он пересоздаётся в [initialize].
|
||||
StreamController<void> _reconnectController = StreamController<void>.broadcast();
|
||||
|
||||
Stream<ChannelReadEvent>? _directChatStream;
|
||||
Stream<ChannelReadEvent>? _clientTypingStream;
|
||||
|
||||
@@ -49,7 +56,17 @@ class WsManager {
|
||||
|
||||
Stream<ChannelReadEvent>? get clientTypingStream => _clientTypingStream;
|
||||
|
||||
/// Сигнал о реконнекте сокета: эмитится после повторной подписки на каналы.
|
||||
///
|
||||
/// Подписчики используют его, чтобы догрузить пропущенные за время обрыва
|
||||
/// сообщения (S5).
|
||||
Stream<void> get reconnected => _reconnectController.stream;
|
||||
|
||||
Future<void> initialize() async {
|
||||
if (_reconnectController.isClosed) {
|
||||
_reconnectController = StreamController<void>.broadcast();
|
||||
}
|
||||
|
||||
if (client == null) {
|
||||
try {
|
||||
if (!await TokenStorage.haveTokenInStorage()) return;
|
||||
@@ -108,10 +125,7 @@ class WsManager {
|
||||
|
||||
_lifecycleSubscription = client?.lifecycleStream.listen((data) {
|
||||
if (data == PusherChannelsClientLifeCycleState.establishedConnection) {
|
||||
_unsubscribe();
|
||||
_subscribe();
|
||||
_privateDirectChatChannel?.subscribe();
|
||||
_presenceDirectChatChannel?.subscribe();
|
||||
handleConnectionEstablished();
|
||||
}
|
||||
});
|
||||
_eventSubscription = client?.eventStream.listen((event) {
|
||||
@@ -301,6 +315,19 @@ class WsManager {
|
||||
_privateNotificationChannel?.unsubscribe();
|
||||
}
|
||||
|
||||
/// Повторно подписывается на каналы и сигналит подписчикам о реконнекте.
|
||||
///
|
||||
/// Вызывается при `establishedConnection` — в том числе после обрыва сети.
|
||||
/// Публичный, чтобы сигнал [reconnected] покрывался тестами без реального
|
||||
/// Pusher-клиента.
|
||||
void handleConnectionEstablished() {
|
||||
_unsubscribe();
|
||||
_subscribe();
|
||||
_privateDirectChatChannel?.subscribe();
|
||||
_presenceDirectChatChannel?.subscribe();
|
||||
_reconnectController.add(null);
|
||||
}
|
||||
|
||||
void subscribeDirectChatChannel() {
|
||||
_privateDirectChatChannel?.subscribe();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user