public async ValueTask BindAsync(IPEndPoint endPoint) { if (!Connected) { UdpClient = new UdpClient(endPoint); _logger.LogInformation($"Starting listening on {endPoint}."); //Create a new thread to receive and process data. Tasks.Enqueue(Task.Run(async() => { while (true) { var data = await UdpClient.ReceiveAsync(); if (!PendingReceive.ContainsKey(data.RemoteEndPoint)) { PendingReceive.AddOrUpdate(data.RemoteEndPoint, new ConcurrentQueue <byte[]>(), (_, queue) => queue); PendingConnection.Enqueue(data.RemoteEndPoint); HavePendingSend.AddOrUpdate(data.RemoteEndPoint, false, (_, b) => b); PendingSend.AddOrUpdate(data.RemoteEndPoint, new ConcurrentQueue <byte[]>(), (_, queue) => queue); } // 0 for normal content if (data.Buffer[0] == 0) { _logger.LogInformation($"Received a standard packet from {data.RemoteEndPoint}."); var pendingReceive = PendingReceive[data.RemoteEndPoint]; //Add data to pending receive pendingReceive.Enqueue(data.Buffer[4..]); //Reply received await UdpClient.SendAsync(new byte[] { 2, 0, 0, 0 }, 4, data.RemoteEndPoint); } // 1 for receive feedback if (data.Buffer[0] == 1) { _logger.LogInformation($"Received a confirm packet from {data.RemoteEndPoint}."); //Enqueue confirmed info ConfirmedReceived.Enqueue(data.RemoteEndPoint); } }
public WithinSentRequest <TRequest> Receive <T>(SelectiveConsumer <T> consumer) { PendingReceive receive = _inbox.Receive <T>(candidate => { Consumer <T> accepted = consumer(candidate); if (accepted == null) { return(null); } return(message => { accepted(message); Complete(); }); }, _timeout, HandleTimeout); _receives.Add(receive); return(this); }