socket.dart 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. import 'dart:convert';
  2. import 'package:nanoid/nanoid.dart';
  3. import 'package:web_socket_channel/io.dart';
  4. import './config.dart';
  5. import './controller.dart';
  6. String getApiUrlWithProtocol() {
  7. final String baseUrl = config['apiUrl'];
  8. if (baseUrl.startsWith('//')) {
  9. return "https://$baseUrl";
  10. }
  11. return baseUrl;
  12. }
  13. String getWebSocketUrl() {
  14. String apiUrlWithProtocol = getApiUrlWithProtocol();
  15. String protocol = apiUrlWithProtocol.substring(0, apiUrlWithProtocol.indexOf('//'));
  16. String apiUrlWithoutProtocol = apiUrlWithProtocol.substring(apiUrlWithProtocol.indexOf('//') + 2);
  17. return "${(protocol == 'https:') ? 'wss' : 'ws'}://$apiUrlWithoutProtocol/pubsub";
  18. }
  19. String getUniqueName(String name) {
  20. return "$name-${nanoid(5)}";
  21. }
  22. const socketKeepaliveTimeoutMs = 20000;
  23. Future keepalive(IOWebSocketChannel channel) {
  24. return new Future.delayed(const Duration(milliseconds: socketKeepaliveTimeoutMs), () {
  25. channel.sink.add(jsonEncode({'type': 'PING'}));
  26. keepalive(channel);
  27. });
  28. }
  29. void connect(Controller controller) async {
  30. if (controller.name.value.length == 0) {
  31. return;
  32. }
  33. final String uniqueName = getUniqueName(controller.name.value);
  34. controller.setUniqueName(uniqueName);
  35. final String webSocketUrl = getWebSocketUrl();
  36. final String pubsubUrl = "$webSocketUrl?client-name=$uniqueName";
  37. print("Connecting to socket: $pubsubUrl");
  38. var channel = IOWebSocketChannel.connect(Uri.parse(pubsubUrl));
  39. controller.channel = channel;
  40. channel.stream.listen((message) {
  41. controller.onRemoteMessage(message);
  42. });
  43. keepalive(channel);
  44. }