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); } }
protected bool HandlerMessage(OwnTcpMessage message) { string topic; Guid id; return(ContainsPlaylist(message.Topic, out topic, out id) ? HandlePlaylistMessage(id, topic, message.Payload) : HandleServiceMessage(topic, message.Payload)); }
protected override async Task SendAsync(string topic, byte[] payload, bool fireAndForget) { if (isSyncing || !IsOpen || IsTopicLocked(topic, payload)) { return; } await connection.SendQueue.Enqueue(OwnTcpMessage.FromData(topic, payload, fireAndForget)); }
protected static IEnumerable <byte> GetBytes(OwnTcpMessage message) { byte[] idBytes = BitConverter.GetBytes(message.ID); byte[] fireAndForgetBytes = BitConverter.GetBytes(message.IsFireAndForget); byte[] topicBytes = Encoding.UTF8.GetBytes(message.Topic); byte[] topicLengthBytes = BitConverter.GetBytes(topicBytes.Length); byte[] payloadLengthBytes = BitConverter.GetBytes(message.Payload?.Length ?? -1); return(idBytes.Concat(fireAndForgetBytes) .Concat(topicLengthBytes) .Concat(topicBytes) .Concat(payloadLengthBytes) .Concat(message.Payload ?? new byte[0])); }
public override async Task SendCommand(string cmd) { if (!IsOpen) { return; } byte[] payload = Encoding.UTF8.GetBytes(cmd); OwnTcpMessage message = new OwnTcpMessage() { IsFireAndForget = true, Topic = cmdString, Payload = payload, }; await connection.SendQueue.Enqueue(message); }
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); }
public Task Enqueue(OwnTcpMessage message) { lock (queue) { OwnTcpSendMessage sendMessage; if (dict.TryGetValue(message.Topic, out sendMessage)) { sendMessage.Message = message; } else { sendMessage = new OwnTcpSendMessage(message); queue.Enqueue(message.Topic); dict.Add(message.Topic, sendMessage); Monitor.Pulse(queue); } return(sendMessage.Task); } }
public async Task SendCommand(string cmd, bool fireAndForget, Task cancelTask = null) { if (!Client.Connected) { return; } Task cmdTask = SendQueue.Enqueue(OwnTcpMessage.FromCommand(cmd, fireAndForget)); if (cancelTask != null) { await Task.WhenAny(cmdTask, cancelTask).ConfigureAwait(false); if (!cmdTask.IsCompleted) { throw new TimeoutException($"Command ran in timout: {cmd}"); } } else { await cmdTask.ConfigureAwait(false); } }
public OwnTcpSendMessage(OwnTcpMessage message) { Message = message; }
private async Task ReceiveHandler(OwnTcpClientConnection connection) { try { while (connection.Client?.Connected == true) { OwnTcpMessage message = await connection.ReadMessage(); if (message == null || connection.Client?.Connected != true) { break; } switch (message.Topic) { case AnwserCmd: int code = BitConverter.ToInt32(message.Payload, 0); if (code == 200) { connection.Waits[message.ID].SetResult(true); connection.Waits.Remove(message.ID); } else { await connection.CloseAsync(new Exception("Negative Answer"), false); } break; case CloseCmd: Exception e = new Exception("Server sent close"); await connection.CloseAsync(e, false); return; case SyncCmd: ByteQueue data = message.Payload; void syncAction() => data.DequeueService(connection.Service, Service.CreateSourcePlaylist, Service.CreatePlaylist); if (helper == null) { syncAction(); } else { await helper.InvokeDispatcher(syncAction); } connection.Waits[message.ID].SetResult(true); connection.Waits.Remove(message.ID); break; default: if (connection.IsSynced) { await connection.ProcessQueue.Enqueue(message); } break; } } } catch (Exception e) { await connection.CloseAsync(new Exception("ReceiveHandler error", e), false); } }