This repository has been archived on 2025-08-25. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
Seshat/lib/data/services/websocket_client.dart

82 lines
2.2 KiB
Dart

import 'dart:async';
import 'dart:convert';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:logger/logger.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<dynamic> _baseController = BehaviorSubject();
final BehaviorSubject<Owner> _ownersController = BehaviorSubject<Owner>(
sync: true,
);
late final StreamSubscription sub;
Logger log = Logger(
printer: PrettyPrinter(
colors: true,
lineLength: 100,
methodCount: 0,
dateTimeFormat: DateTimeFormat.dateAndTime,
),
);
Stream<Owner> get owners => _ownersController.stream;
Future<void> _initStore() async {
_secureStorage ??= const FlutterSecureStorage();
}
Future<void> connect() async {
final url = "wss://$apiBasePath/ws";
log.i("Webocket: $url");
await _initStore();
if (_channel != null) return;
_channel = WebSocketChannel.connect(Uri.parse(url));
await _channel!.ready;
var token = await _secureStorage!.read(key: "token");
_channel!.sink.add(jsonEncode({"token": "$token"}));
_channel!.stream.listen((message) {
_baseController.add(message);
});
var data = await _baseController.stream.first;
var result = jsonDecode(data);
if (result["type"] == "auth_success") {
sub = _baseController.stream.listen(
(message) {
final Map<String, dynamic> data = jsonDecode(message);
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();
}
}