2024-05-26 05:39:21 +00:00
|
|
|
import 'dart:async';
|
|
|
|
import 'dart:convert';
|
|
|
|
import 'dart:io';
|
|
|
|
|
|
|
|
import 'package:get/get.dart';
|
|
|
|
import 'package:solian/models/packet.dart';
|
|
|
|
import 'package:solian/providers/auth.dart';
|
|
|
|
import 'package:solian/services.dart';
|
|
|
|
import 'package:web_socket_channel/io.dart';
|
|
|
|
|
|
|
|
class ChatProvider extends GetxController {
|
|
|
|
RxBool isConnected = false.obs;
|
|
|
|
RxBool isConnecting = false.obs;
|
|
|
|
|
|
|
|
IOWebSocketChannel? websocket;
|
|
|
|
|
|
|
|
StreamController<NetworkPackage> stream = StreamController.broadcast();
|
|
|
|
|
|
|
|
void connect({noRetry = false}) async {
|
2024-06-03 15:36:46 +00:00
|
|
|
if (isConnected.value) {
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
disconnect();
|
|
|
|
}
|
2024-06-02 15:20:34 +00:00
|
|
|
|
2024-05-26 05:39:21 +00:00
|
|
|
final AuthProvider auth = Get.find();
|
|
|
|
if (!await auth.isAuthorized) throw Exception('unauthorized');
|
|
|
|
|
|
|
|
if (auth.credentials == null) await auth.loadCredentials();
|
|
|
|
|
|
|
|
final uri = Uri.parse(
|
|
|
|
'${ServiceFinder.services['messaging']}/api/ws?tk=${auth.credentials!.accessToken}'
|
|
|
|
.replaceFirst('http', 'ws'),
|
|
|
|
);
|
|
|
|
|
|
|
|
isConnecting.value = true;
|
|
|
|
|
|
|
|
try {
|
|
|
|
websocket = IOWebSocketChannel.connect(uri);
|
|
|
|
await websocket?.ready;
|
|
|
|
} catch (e) {
|
|
|
|
if (!noRetry) {
|
|
|
|
await auth.refreshCredentials();
|
|
|
|
return connect(noRetry: true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
listen();
|
|
|
|
|
|
|
|
isConnected.value = true;
|
|
|
|
isConnecting.value = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void disconnect() {
|
|
|
|
websocket?.sink.close(WebSocketStatus.normalClosure);
|
2024-06-02 15:20:34 +00:00
|
|
|
websocket = null;
|
2024-05-26 05:39:21 +00:00
|
|
|
isConnected.value = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void listen() {
|
|
|
|
websocket?.stream.listen(
|
|
|
|
(event) {
|
|
|
|
final packet = NetworkPackage.fromJson(jsonDecode(event));
|
|
|
|
stream.sink.add(packet);
|
|
|
|
},
|
|
|
|
onDone: () {
|
|
|
|
isConnected.value = false;
|
2024-06-01 13:41:40 +00:00
|
|
|
Future.delayed(const Duration(milliseconds: 1000), () => connect());
|
2024-05-26 05:39:21 +00:00
|
|
|
},
|
|
|
|
onError: (err) {
|
|
|
|
isConnected.value = false;
|
2024-06-01 13:41:40 +00:00
|
|
|
Future.delayed(const Duration(milliseconds: 1000), () => connect());
|
2024-05-26 05:39:21 +00:00
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|