Exemplo n.º 1
0
        private async Task DataReceiver(ClientMetadata client, CancellationToken?cancelToken = null)
        {
            var clientId = client.IpPort();

            try
            {
                #region Wait-for-Data

                while (true)
                {
                    cancelToken?.ThrowIfCancellationRequested();

                    byte[] data = await MessageReadAsync(client);

                    if (data != null)
                    {
                        if (MessageReceived != null)
                        {
                            var _ = Task.Run(() => MessageReceived?.Invoke(client.IpPort(), data), CancellationToken.None);
                        }
                    }
                    else
                    {
                        // no message available
                        await Task.Delay(30, cancelToken.GetValueOrDefault());
                    }
                }

                #endregion
            }
            catch (OperationCanceledException oce)
            {
                Log("DataReceiver client " + clientId + " disconnected (canceled): " + oce.Message);
            }
            catch (WebSocketException wse)
            {
                Log("DataReceiver client " + clientId + " disconnected (websocket exception): " + wse.Message);
            }
            finally
            {
                if (RemoveClient(client))
                {
                    // must only fire disconnected event if the client was previously connected. Note that
                    // multithreading gives multiple disconnection events from the socket, the reader and the writer
                    ClientDisconnected?.Invoke(clientId);
                    client.Ws.Dispose();
                    Log("DataReceiver client " + clientId + " disconnected (now " + _Clients.Count + " clients active)");
                }
            }
        }
Exemplo n.º 2
0
        private async Task <bool> MessageWriteAsync(ClientMetadata client, byte[] data, WebSocketMessageType messageType)
        {
            try
            {
                #region Send-Message

                // Cannot have two simultaneous SendAsync calls so use a
                // semaphore to block the second until the first has completed

                await client.SendAsyncLock.WaitAsync(client.KillToken.Token);

                try
                {
                    await client.Ws.SendAsync(new ArraySegment <byte>(data, 0, data.Length),
                                              messageType, true, client.KillToken.Token);
                }
                finally
                {
                    client.SendAsyncLock.Release();
                }

                return(true);

                #endregion
            }
            catch (Exception e)
            {
                Log("*** MessageWriteAsync " + client.IpPort() + " disconnected due to exception " + e);
                return(false);
            }
        }
Exemplo n.º 3
0
 private bool RemoveClient(ClientMetadata client)
 {
     return(_Clients.TryRemove(client.IpPort(), out var removedClient));
 }
Exemplo n.º 4
0
 private bool AddClient(ClientMetadata client)
 {
     _Clients.TryRemove(client.IpPort(), out var removedClient);
     return(_Clients.TryAdd(client.IpPort(), client));
 }