| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- import 'dart:async';
- import 'dart:convert';
- import 'dart:io';
- import 'package:get/get.dart';
- import 'package:nanoid/nanoid.dart';
- import 'package:web_socket_channel/io.dart';
- import './actions.dart' as actions;
- import './controller.dart';
- String getWebSocketUrl(String apiUrl) {
- return "wss://$apiUrl/pubsub";
- }
- String getUniqueName(String name) {
- return "$name-${nanoid(5)}";
- }
- const socketKeepaliveTimeoutMs = 30000;
- class Socket {
- WebSocket conn;
- IOWebSocketChannel channel;
- RxBool connected = false.obs;
- RxString error = ''.obs;
- void _keepalive() {
- var future = new Future.delayed(const Duration(milliseconds: socketKeepaliveTimeoutMs));
- void ping(dynamic data) {
- channel.sink.add(jsonEncode({'type': 'PING'}));
- _keepalive();
- }
- var subscription = future.asStream().listen(ping);
- channel.sink.done.whenComplete(() {
- subscription.cancel();
- });
- }
- Future<String> connect(
- String apiUrl,
- String name,
- void Function(String) onRemoteMessage,
- ) async {
- if (apiUrl == null || name == null || apiUrl.length == 0 || name.length == 0) {
- return null;
- }
- final String uniqueName = getUniqueName(name);
- final String webSocketUrl = getWebSocketUrl(apiUrl);
- final String pubsubUrl = "$webSocketUrl?client-name=$uniqueName";
- connected.value = false;
- try {
- conn = await WebSocket
- .connect(Uri.parse(pubsubUrl).toString())
- .timeout(Duration(seconds: 10));
- channel = IOWebSocketChannel(conn);
- channel.stream.listen((message) => onRemoteMessage(message));
- connected.value = true;
- error.value = '';
- _keepalive();
- }
- on SocketException {
- error.value = "Error connecting to socket";
- }
- on TimeoutException {
- error.value = "Timeout connecting to socket";
- }
- catch (err) {
- error.value = "Unknown error connecting to socket";
- }
- return uniqueName;
- }
- void disconnect() {
- conn?.close();
- }
- void dispatch(String action) {
- if (channel == null) {
- return;
- }
- channel.sink.add(action);
- }
- }
- void onRemoteMessage(Controller controller, String message) {
- var action = jsonDecode(message);
- switch (action['type']) {
- case actions.CLIENT_LIST_UPDATED:
- var payload = action['payload'];
- List<Client> clientList = [];
- for (var i = 0; i < payload.length; i++) {
- clientList.add(new Client(
- payload[i]['name'],
- payload[i]['lastPing'],
- ));
- }
- controller.setClients(clientList);
- break;
- case actions.STATE_SET:
- Player nextPlayer = new Player();
- nextPlayer.currentTime = action['payload']['currentTime'].toDouble();
- nextPlayer.seekTime = action['payload']['seekTime'].toDouble();
- nextPlayer.master = action['payload']['master'];
- nextPlayer.songId = action['payload']['songId'];
- nextPlayer.playing = action['payload']['playing'];
- nextPlayer.queue = [];
- for (var i = 0; i < action['payload']['queue'].length; i++) {
- nextPlayer.queue.add(action['payload']['queue'][i]);
- }
- controller.player.value = nextPlayer;
- break;
- }
- }
|