private async Task SendToAllSockets(SuperWebSocketWrapper socketThatReceivedData, string message)
 {
     foreach (var wrappedSocket in _wrappedSockets.Values)
     {
         // do not echo back to the socket that sent this
         if (socketThatReceivedData != null && socketThatReceivedData.SocketId == wrappedSocket.SocketId)
         {
             _logger.LogDebug("Suppressing echo to source socket ({1})", wrappedSocket.SocketId);
         }
         else
         {
             try
             {
                 _logger.LogDebug("Sending ({0}) to Socket ({1})", message, wrappedSocket.SocketId);
                 await wrappedSocket.SendData(message);
             }
             catch (Exception e)
             {
                 _logger.LogWarning(e, "Send data to socket ({0}) failed. Cleaning up socket.", wrappedSocket.SocketId);
                 // TODO: what does this do to the iterator?
                 RemoveWebSocketWrapperFromPool(wrappedSocket);
             }
         }
     }
 }
        // takes an accepted native socket and "runs" it within
        // the pool of sockets this manager maintains.
        internal async Task RunSocket(WebSocket nativeWebSocket)
        {
            var webSocketWrapper = new SuperWebSocketWrapper(
                nativeWebSocket,
                this.GetNextSocketId(),
                this.SocketReceivedData);

            AddWebSocketWrapperToPool(webSocketWrapper);

            string socketCloseReason = null;

            try
            {
                _logger.LogDebug("Added socket ({0}) to pool, running", webSocketWrapper.SocketId);
                socketCloseReason = await webSocketWrapper.Run();
            }
            finally
            {
                _logger.LogDebug("Removing Socket ({0}) from pool. Close reason [{1}]", webSocketWrapper.SocketId, socketCloseReason);
                RemoveWebSocketWrapperFromPool(webSocketWrapper);
            }
        }
 private async Task SocketReceivedData(SuperWebSocketWrapper socketThatReceivedData, string data)
 {
     // sending source socket to suppress echos
     await SendToAllSockets(socketThatReceivedData, data);
 }
        private void RemoveWebSocketWrapperFromPool(SuperWebSocketWrapper webSocketWrapper)
        {
            SuperWebSocketWrapper removedWebSocketWrapper;

            _wrappedSockets.TryRemove(webSocketWrapper.SocketId, out removedWebSocketWrapper);
        }
 private void AddWebSocketWrapperToPool(SuperWebSocketWrapper webSocketWrapper)
 {
     _wrappedSockets.TryAdd(webSocketWrapper.SocketId, webSocketWrapper);
 }