97 lines
2.6 KiB
Dart
97 lines
2.6 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';
|
|
|
|
/// API Client to manages connections to WebSockets
|
|
class WebsocketClient {
|
|
/// Storage to access JWT
|
|
FlutterSecureStorage? _secureStorage;
|
|
|
|
/// Raw channel of data from WebSocket
|
|
WebSocketChannel? _channel;
|
|
|
|
/// Global WebSocket Stream
|
|
final BehaviorSubject<dynamic> _baseController = BehaviorSubject();
|
|
|
|
/// WebSocket Stream dedicated to [Owner] entries
|
|
final BehaviorSubject<Owner> _ownersController = BehaviorSubject<Owner>(
|
|
sync: true,
|
|
);
|
|
|
|
/// Subscription to [_baseController]
|
|
late final StreamSubscription sub;
|
|
Logger log = Logger(
|
|
printer: PrettyPrinter(
|
|
colors: true,
|
|
lineLength: 100,
|
|
methodCount: 0,
|
|
dateTimeFormat: DateTimeFormat.dateAndTime,
|
|
),
|
|
);
|
|
|
|
/// Gets a stream of [Owner]
|
|
Stream<Owner> get owners => _ownersController.stream;
|
|
|
|
/// Initializes connection to the [_secureStorage]
|
|
Future<void> _initStore() async {
|
|
_secureStorage ??= const FlutterSecureStorage();
|
|
}
|
|
|
|
/// Connects to the websocket
|
|
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();
|
|
},
|
|
);
|
|
}
|
|
}
|
|
|
|
/// Disconnects from the websocket
|
|
void _handleDisconnect() {
|
|
sub.cancel();
|
|
_channel = null;
|
|
}
|
|
|
|
/// Closes all connections
|
|
void dispose() {
|
|
sub.cancel();
|
|
_channel?.sink.close();
|
|
_ownersController.close();
|
|
}
|
|
}
|