import 'dart:async'; import 'package:web_socket_channel/web_socket_channel.dart'; abstract interface class RelayConnection { Future connect(); Future send(String message); Stream get messages; Future close(); } final class WebSocketRelayConnection implements RelayConnection { final String _url; WebSocketChannel? _channel; StreamController? _controller; WebSocketRelayConnection(String url) : _url = url; @override Future connect() async { _channel = WebSocketChannel.connect(Uri.parse(_url)); await _channel!.ready; _controller = StreamController(); _channel!.stream.cast().listen( _controller!.add, onError: _controller!.addError, onDone: _controller!.close, ); } @override Future send(String message) async => _channel!.sink.add(message); @override Stream get messages => _controller!.stream; @override Future close() async { await _channel?.sink.close(); _channel = null; _controller = null; } }