Solian/lib/providers/websocket.dart

86 lines
2.3 KiB
Dart
Raw Permalink Normal View History

2024-06-08 13:35:50 +00:00
import 'dart:async';
2024-05-25 05:00:40 +00:00
import 'dart:convert';
2024-06-08 13:35:50 +00:00
import 'dart:developer';
2024-05-25 05:00:40 +00:00
import 'dart:io';
import 'package:get/get.dart';
import 'package:solian/models/notification.dart';
import 'package:solian/models/packet.dart';
import 'package:solian/providers/auth.dart';
2024-10-15 16:50:48 +00:00
import 'package:solian/providers/notifications.dart';
2024-05-25 05:00:40 +00:00
import 'package:solian/services.dart';
2024-07-06 09:39:19 +00:00
import 'package:web_socket_channel/web_socket_channel.dart';
2024-05-25 05:00:40 +00:00
class WebSocketProvider extends GetxController {
2024-05-25 05:00:40 +00:00
RxBool isConnected = false.obs;
RxBool isConnecting = false.obs;
2024-07-06 09:39:19 +00:00
WebSocketChannel? websocket;
2024-05-25 05:00:40 +00:00
StreamController<NetworkPackage> stream = StreamController.broadcast();
2024-07-26 17:39:20 +00:00
Future<void> connect({noRetry = false}) async {
2024-06-03 15:36:46 +00:00
if (isConnected.value) {
return;
} else {
disconnect();
}
2024-05-25 05:00:40 +00:00
final AuthProvider auth = Get.find();
try {
await auth.ensureCredentials();
2024-05-25 05:00:40 +00:00
final uri = Uri.parse(ServiceFinder.buildUrl(
'dealer',
'/api/ws?tk=${auth.credentials!.accessToken}',
).replaceFirst('http', 'ws'));
2024-05-25 05:00:40 +00:00
isConnecting.value = true;
2024-05-25 05:00:40 +00:00
2024-07-06 09:39:19 +00:00
websocket = WebSocketChannel.connect(uri);
2024-05-25 05:00:40 +00:00
await websocket?.ready;
listen();
isConnected.value = true;
} catch (err) {
log('Unable connect dealer via websocket... $err');
2024-05-25 05:00:40 +00:00
if (!noRetry) {
await auth.refreshCredentials();
return connect(noRetry: true);
}
} finally {
isConnecting.value = false;
2024-05-25 05:00:40 +00:00
}
}
void disconnect() {
websocket?.sink.close(WebSocketStatus.normalClosure);
websocket = null;
2024-05-25 05:00:40 +00:00
isConnected.value = false;
}
void listen() {
websocket?.stream.listen(
(event) {
final packet = NetworkPackage.fromJson(jsonDecode(event));
2024-08-23 14:43:04 +00:00
log('Websocket incoming message: ${packet.method} ${packet.message}');
stream.sink.add(packet);
2024-09-15 09:19:55 +00:00
if (packet.method == 'notifications.new') {
2024-10-15 16:50:48 +00:00
final NotificationProvider nty = Get.find();
nty.notifications.add(Notification.fromJson(packet.payload!));
nty.notificationUnread.value++;
2024-09-15 09:19:55 +00:00
}
2024-05-25 05:00:40 +00:00
},
onDone: () {
isConnected.value = false;
2024-06-08 13:35:50 +00:00
Future.delayed(const Duration(seconds: 1), () => connect());
2024-05-25 05:00:40 +00:00
},
onError: (err) {
isConnected.value = false;
Future.delayed(const Duration(seconds: 3), () => connect());
2024-05-25 05:00:40 +00:00
},
);
}
}