LCOV - code coverage report
Current view: top level - services - client_connections_service.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 0 42 0.0 %
Date: 2022-03-03 12:14:56 Functions: 0 0 -

          Line data    Source code
       1             : import 'dart:convert';
       2             : 
       3             : import 'package:fast_immutable_collections/fast_immutable_collections.dart';
       4             : import 'package:web_socket_channel/web_socket_channel.dart';
       5             : import 'package:ws_game_server_types/ws_game_server_types.dart';
       6             : 
       7             : /// All of the user connections are kept by the [ClientConnectionsService] object,
       8             : /// which keeps a map of [WebSocketChannel]s to userIds.
       9             : ///
      10             : /// When a user connection is added or removed the [OtherPlayerIds] is broadcast.
      11             : class ClientConnectionsService {
      12             :   // We can constructor inject the message handler function used by shelf_web_socket
      13           0 :   ClientConnectionsService([Function(WebSocketChannel)? messageHandler]) {
      14           0 :     _messageHandler = messageHandler ?? defaultMessageHandler;
      15             :   }
      16             : 
      17             :   final presenceMap = <WebSocketChannel, String>{};
      18             : 
      19             :   // We keep the handler function as a member so that different handlers can
      20             :   // be constructor injected.
      21             :   late final Function(WebSocketChannel) _messageHandler;
      22             : 
      23             :   // The default function that [_messageHandler] is set to.
      24           0 :   void defaultMessageHandler(WebSocketChannel webSocket) {
      25             :     // Now attach a listener to the websocket that will perform the ongoing logic
      26           0 :     webSocket.stream.listen(
      27           0 :       (jsonString) {
      28           0 :         final jsonData = jsonDecode(jsonString);
      29             :         // If a user is announcing their presence, store the webSocket against the
      30             :         // userId and broadcast the current connections
      31           0 :         if (jsonData['type'] == PresentMessage.jsonType) {
      32           0 :           print(
      33           0 :               'server received: $jsonString \nAdding user & broadcasting other player list');
      34           0 :           _addAndBroadcast(webSocket, jsonData['userId'] as String);
      35           0 :         } else if (jsonData['type'] == OtherPlayerIdsMessage.jsonType) {
      36           0 :           print('server received: $jsonString, broadcasting other player ids');
      37           0 :           _broadcastOtherPlayerIds();
      38           0 :         } else if (jsonData['type'] == PlayerPathMessage.jsonType) {
      39           0 :           print('server received: $jsonString, broadcasting');
      40           0 :           _broadcastPlayerPath(jsonData);
      41             :         } else {
      42           0 :           throw Exception('Unknown json type in websocket stream: $jsonData');
      43             :         }
      44             :       },
      45           0 :       onError: (error) {
      46           0 :         print(error);
      47           0 :         webSocket.sink.add('$error');
      48             :       },
      49           0 :       onDone: () {
      50           0 :         _removeAndBroadcast(webSocket);
      51             :       },
      52             :     );
      53             :   }
      54             : 
      55           0 :   Function(WebSocketChannel) get messageHandler => _messageHandler;
      56             : 
      57           0 :   void _addAndBroadcast(WebSocketChannel ws, String userId) {
      58           0 :     presenceMap[ws] = userId;
      59           0 :     _broadcastOtherPlayerIds();
      60             :   }
      61             : 
      62           0 :   void _removeAndBroadcast(WebSocketChannel ws) {
      63           0 :     presenceMap.remove(ws);
      64           0 :     _broadcastOtherPlayerIds();
      65             :   }
      66             : 
      67           0 :   void _broadcastOtherPlayerIds() {
      68           0 :     for (final ws in presenceMap.keys) {
      69             :       // make the "other players" list for this player and send
      70           0 :       var otherIdsList = presenceMap.values.toISet().remove(presenceMap[ws]!);
      71             :       final message =
      72           0 :           jsonEncode(OtherPlayerIdsMessage(ids: otherIdsList).toJson());
      73           0 :       ws.sink.add(message);
      74             :     }
      75             :   }
      76             : 
      77           0 :   void _broadcastPlayerPath(JsonMap jsonData) {
      78           0 :     var message = PlayerPathMessage.fromJson(jsonData);
      79           0 :     for (final ws in presenceMap.keys) {
      80           0 :       if (presenceMap[ws]! != message.userId) {
      81           0 :         ws.sink.add(jsonEncode(message.toJson()));
      82             :       }
      83             :     }
      84             :   }
      85             : 
      86           0 :   void _broadcast(String message) {
      87           0 :     for (final ws in presenceMap.keys) {
      88           0 :       ws.sink.add(message);
      89             :     }
      90             :   }
      91             : }

Generated by: LCOV version 1.13