import 'dart:async'; import 'package:meta/meta.dart'; import 'communicator.dart'; import 'heartbeat_mixin.dart'; abstract class BaseClient> extends Communicator with HeartbeatMixin { late final Self _self; final List _disconnectListeners = []; bool _closeCalled = false; @protected void initSelf(Self self) { _self = self; } void addDisconnectListener(void Function(Self) fn) { if (!_disconnectListeners.contains(fn)) { _disconnectListeners.add(fn); } } void removeDisconnectListener(void Function(Self) fn) { _disconnectListeners.remove(fn); } void onDisconnected(dynamic _) { unawaited(_closeWithGrace(false)); } @override Future close() async { await _closeWithGrace(true); } Future _closeWithGrace(bool graceful) async { if (_closeCalled) return; _closeCalled = true; if (graceful) { await super.close(); } else { super.shutdown(); } stopHeartbeat(); await closeTransport(); final listeners = List.from(_disconnectListeners); _disconnectListeners.clear(); for (final fn in listeners) { fn(_self); } } @protected Future closeTransport(); bool get isSourcePaused; }