import 'dart:async'; import 'dart:convert'; import 'package:flutter/foundation.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:rxdart/rxdart.dart'; import 'package:seshat/config/constants.dart'; import 'package:seshat/domain/models/owner.dart'; import 'package:web_socket_channel/web_socket_channel.dart'; class WebsocketClient { WebSocketChannel? _channel; FlutterSecureStorage? _secureStorage; final BehaviorSubject _baseController = BehaviorSubject(); final BehaviorSubject _ownersController = BehaviorSubject( sync: true, ); late final StreamSubscription sub; Stream get owners => _ownersController.stream; Future _initStore() async { _secureStorage ??= const FlutterSecureStorage( aOptions: AndroidOptions(encryptedSharedPreferences: true), ); } Future connect() async { await _initStore(); debugPrint("\n\n\n\nWEBSOCKET STORE IS READY\n\n\n\n"); if (_channel != null) return; debugPrint("\n\n\n\nWEBSOCKET WILL CONNECT\n\n\n\n"); _channel = WebSocketChannel.connect(Uri.parse("wss://$apiBasePath/ws")); debugPrint("\n\n\n\nWEBSOCKET IS CONNECTING\n\n\n\n"); await _channel!.ready; debugPrint("\n\n\n\nWEBSOCKET IS READY\n\n\n\n"); var token = await _secureStorage!.read(key: "token"); _channel!.sink.add(jsonEncode({"token": "$token"})); _channel!.stream.listen((message) { debugPrint("\n\n\n\n[1] Received : $message\n\n\n\n"); _baseController.add(message); }); var data = await _baseController.stream.first; debugPrint("\n\n\n\n$data\n\n\n\n"); var result = jsonDecode(data); if (result["type"] == "auth_success") { debugPrint("\n\n\n\nSUCCESS !\n\n\n\n"); sub = _baseController.stream.listen( (message) { final Map data = jsonDecode(message); debugPrint("\n\n\n\n[2] Transfered : $message\n\n\n\n"); switch (data["type"]) { case "new_owner": final owner = Owner.fromJSON(data["data"]); _ownersController.add(owner); break; default: } }, onDone: _handleDisconnect, onError: (error) { _handleDisconnect(); }, ); } } void _handleDisconnect() { sub.cancel(); _channel = null; } void dispose() { sub.cancel(); _channel?.sink.close(); _ownersController.close(); } }