import 'dart:convert'; import 'package:comunic/helpers/events_helper.dart'; import 'package:comunic/models/api_request.dart'; import 'package:comunic/models/config.dart'; import 'package:comunic/models/ws_message.dart'; import 'package:web_socket_channel/web_socket_channel.dart'; /// User web socket helper /// /// @author Pierre Hubert class WebSocketHelper { static WebSocketChannel _ws; /// Check out whether we are currently connected to WebSocket or not static bool isConnected() { return _ws != null && _ws.closeCode == null; } /// Get WebSocket access token //TODO : Handles the case user tokens were destroyed (auto sign-out user) static Future _getWsToken() async => (await APIRequest(uri: "ws/token", needLogin: true).exec()) .assertOk() .getObject()["token"]; /// Connect to WebSocket static connect() async { if (isConnected()) return; // First, get an access token final token = await _getWsToken(); // Determine WebSocket URI final wsURL = "${(config().apiServerSecure ? "wss" : "ws")}://${config() .apiServerName}${config().apiServerUri}ws?token=$token"; final wsURI = Uri.parse(wsURL); // Connect _ws = WebSocketChannel.connect(wsURI); _ws.stream.listen( // When we got data (data) { print("WS New data: $data"); _processMessage(data.toString()); }, // Print errors on console onError: (e, stack) { print("WS error! $e"); print(stack); }, // Notify when the channel is closed onDone: () { print("WS Channel closed"); EventsHelper.emit(WSClosedEvent()); }, ); } /// Process incoming message static _processMessage(String msgStr) { try { final msg = WsMessage.fromJSON(jsonDecode(msgStr)); if (!msg.hasId) _processUnattendedMessage(msg); else throw Exception("Do not know how to process attended message!"); } catch (e, stack) { print("WS could not process message: $e"); print(stack); } } /// Process an unattended message static _processUnattendedMessage(WsMessage msg) { switch (msg.title) { case "number_notifs": EventsHelper.emit(NewNumberNotifsEvent(msg.data)); break; default: throw Exception("Unknown message type: ${msg.title}"); } } }