private async Task SendClientHandler(OwnTcpServerConnection connection) { uint count = 0; try { while (connection.Client.Connected) { OwnTcpSendMessage send = connection.SendQueue.Dequeue(); if (send == null || !connection.Client.Connected) { break; } if (!send.Message.HasID) { send.Message.ID = count++; } byte[] data = GetBytes(send.Message).ToArray(); await connection.Stream.WriteAsync(data, 0, data.Length); await connection.Stream.FlushAsync(); send.SetResult(true); } } catch (Exception e) { await CloseConnection(connection); } }
private async Task ReadClientHandler(OwnTcpServerConnection connection, AsyncQueue <OwnTcpSendMessage> processQueue) { try { while (connection.Client.Connected) { OwnTcpMessage message = await connection.ReadMessage(); if (message == null || !connection.Client.Connected) { break; } switch (message.Topic) { case PingCmd: await SendAnswer(connection, message.ID, 200); break; case SyncCmd: ByteQueue data = new ByteQueue(); data.Enqueue(Service); await SendMessageToClient(connection, SyncCmd, message.ID, data); break; case CloseCmd: await CloseConnection(connection, false); return; default: OwnTcpSendMessage processItem = new OwnTcpSendMessage(message); await processQueue.Enqueue(processItem); if (await processItem.Task) { Task responseTask = message.IsFireAndForget ? Task.CompletedTask : SendAnswer(connection, message.ID, 200); await SendMessageToAllOtherClients(connection, message.Topic, message.Payload); await responseTask; } else { await CloseConnection(connection); } break; } } } catch (Exception e) { await CloseConnection(connection); } }
private static async Task SendMessageToClient(OwnTcpServerConnection connection, string topic, uint id, byte[] payload = null) { if (!connection.Client.Connected) { return; } OwnTcpMessage message = new OwnTcpMessage() { IsFireAndForget = true, ID = id, Topic = topic, Payload = payload, }; await connection.SendQueue.Enqueue(message).ConfigureAwait(false); }
private async Task CloseConnection(OwnTcpServerConnection connection, bool sendClose = true) { if (!connections.Contains(connection)) { return; } try { if (sendClose) { await SendMessageToClient(connection, CloseCmd, null).ConfigureAwait(false); } } catch { } connection.SendQueue.End(); connection.Client.Dispose(); connections.Remove(connection); }
private async Task NewConnectionsHandler(AsyncQueue <OwnTcpSendMessage> processQueue) { try { while (IsOpen) { TcpClient client = await listener.AcceptTcpClientAsync().ConfigureAwait(false); OwnTcpSendQueue queue = new OwnTcpSendQueue(); OwnTcpServerConnection connection = new OwnTcpServerConnection(client, queue); connections.Add(connection); Task sendTask = Task.Run(() => SendClientHandler(connection)); Task readTask = Task.Run(() => ReadClientHandler(connection, processQueue)); connection.Task = Task.WhenAll(sendTask, readTask); } } catch (Exception e) { await CloseAsync(e, false); } }
private static Task SendMessageToClient(OwnTcpServerConnection connection, string topic, byte[] payload) { return(SendMessageToClient(connection, topic, 0, payload)); }
private Task SendMessageToAllOtherClients(OwnTcpServerConnection srcConnection, string topic, byte[] payload) { return(SendMessageToClients(connections.Where(c => c != srcConnection), topic, payload)); }
private static Task SendAnswer(OwnTcpServerConnection connection, uint id, int value) { return(SendMessageToClient(connection, AnwserCmd, id, BitConverter.GetBytes(value))); }