我有一个 Windows 控制台应用程序,旨在侦听 TCP 消息并将它们传递给处理程序。 我的问题是当处理程序忙于处理时。它阻止 TCP 侦听器接收新消息。我希望侦听器可以管理许多并发消息并且不会被任何其他处理阻塞。有没有办法让监听器异步。
TCP 监听器
using Abp.Dependency;
using Abp.Reflection.Extensions;
using Erx.Middleware.Configuration;
using Erx.Middleware.TCPCommunicator.Handlers;
using Microsoft.Extensions.Configuration;
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Erx.Middleware.TCPCommunicator.Executer
{
public class TcpListenerExecuter : ITransientDependency
{
private readonly Log _log;
private readonly IConfigurationRoot _appConfiguration;
TcpListener tcpListener = null;
TcpPLCClientExecuter _tcpPLCClientExecuter;
MessageHandler _messageHandler;
public TcpListenerExecuter(
Log log, TcpPLCClientExecuter tcpPLCClientExecuter,
MessageHandler messageHandler)
{
_log = log;
_messageHandler = messageHandler;
_tcpPLCClientExecuter = tcpPLCClientExecuter;
_appConfiguration = AppConfigurations.Get(
typeof(TcpCommunicatorModule).GetAssembly().GetDirectoryPathOrNull()
);
}
public void Run()
{
var port = _appConfiguration.GetValue<string>("ServerDetails:Port");
var localAddr = IPAddress.Parse(_appConfiguration.GetValue<string>("ServerDetails:IpAddress"));
tcpListener = new TcpListener(localAddr, Convert.ToInt32(port));
tcpListener.Start();
StartListener();
}
public void StartListener()
{
try
{
while (true)
{
_log.Write("Waiting for a connection...");
TcpClient client = tcpListener.AcceptTcpClient();
_log.Write("Connected!");
Thread t = new Thread(new ParameterizedThreadStart(HandleDeivce));
t.Start(client);
}
}
catch (Exception e)
{
_log.Error(e.Message);
_log.Error(e.StackTrace);
}
finally
{
// Stop listening for new clients.
tcpListener.Stop();
}
Console.Read();
}
public void HandleDeivce(object obj)
{
var client = (TcpClient)obj;
var stream = client.GetStream();
byte[] bytes = new byte[256];
int i;
try
{
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
string data = Encoding.ASCII.GetString(bytes, 0, i);
_log.Write("Received:" + data + " thread:" + Thread.CurrentThread.ManagedThreadId);
var response = _messageHandler.ValidateMessage(data);
byte[] reply = Encoding.ASCII.GetBytes(response + " - " + data);
stream.Write(reply, 0, reply.Length);
_log.Write("Sent:" + response + ":" + data + " thread:" + Thread.CurrentThread.ManagedThreadId);
if (response == "OK")
{
_messageHandler.HandleMessages(data).GetAwaiter().GetResult();
}
}
}
catch (Exception e) //TODO : FIX THIS ERROR HANDLE
{
_log.Error(e.Message);
_log.Error(e.StackTrace);
//client.Close();
//client.Close();
}
}
}
}
处理程序 - ASYNC AWAIT 函数正在阻塞侦听器
using Abp.Dependency;
using Abp.Events.Bus;
using Abp.Reflection.Extensions;
using Abp.Timing;
using Erx.Middleware.Configuration;
using Erx.Middleware.TCPCommunicator.Domain;
using Erx.Middleware.TCPCommunicator.Executer;
using Erx.Middleware.TCPCommunicator.Messages;
using Erx.Middleware.TCPCommunicator.Models;
using Microsoft.Extensions.Configuration;
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Erx.Middleware.TCPCommunicator.Handlers
{
public class MessageHandler : ITransientDependency
{
public bool IsSystemStopped { get; set; } = false;
public bool IsPSystemStopped { get; set; } = false;
public bool IsDestackerStopped { get; set; } = false;
public bool IsPDestackerStopped { get; set; } = false;
public bool IsInitError { get; set; } = false;
private readonly Log _log;
private readonly IConfigurationRoot _appConfiguration;
TcpPLCClientExecuter _tcpPLCClientExecuter;
PLCMessages _PlcMessages;
WorkItemManager _workItemManager;
PrinterManager _printerManager;
PdCommunicationsManager _pdCommunicationsManager;
TcpMEKAExecuter _tcpMEKAExecuter;
MKItemManager _mKItemManager;
RDLCommunicationsManager _rdlManager;
public IEventBus EventBus { get; set; }
public MessageHandler(
Log log,
TcpPLCClientExecuter tcpPLCClientExecuter,
PLCMessages PlcMessages,
WorkItemManager workItemManager,
PrinterManager printerManager,
PdCommunicationsManager pdCommunicationsManager,
TcpMEKAExecuter tcpMEKAExecuter,
MKItemManager mKItemManager,
RDLCommunicationsManager rdlManager)
{
_log = log;
_tcpPLCClientExecuter = tcpPLCClientExecuter;
_PlcMessages = PlcMessages;
_workItemManager = workItemManager;
_printerManager = printerManager;
_pdCommunicationsManager = pdCommunicationsManager;
_tcpMEKAExecuter = tcpMEKAExecuter;
_mKItemManager = mKItemManager;
_rdlManager = rdlManager;
EventBus = NullEventBus.Instance;
_appConfiguration = AppConfigurations.Get(
typeof(TcpCommunicatorModule).GetAssembly().GetDirectoryPathOrNull()
);
}
public string ValidateMessage(string message)
{
var length1 = 4 + MiddlewareConsts.NullBarcodeString.Length;
var length2 = 31 + MiddlewareConsts.NullBarcodeString.Length;
if (message.Length != length1)
{
return "Invalid Message Length";
}
if (message.Length > length1 && message.Length != length2)
{
return "Invalid Message Length";
}
return "OK";
}
async Task PutTaskDelay(int delay)
{
await Task.Delay(delay);
}
public async Task HandleMessages(string message)
{
try
{
var code = message.Substring(0, 2);
var barcode = message.Substring(2, MiddlewareConsts.NullBarcodeString.Length);
var pos = 3 + MiddlewareConsts.NullBarcodeString.Length;
var pos2 = 2 + MiddlewareConsts.NullBarcodeString.Length;
var rule = message.Substring(pos, 1);
var type = message.Substring(pos2, 1);
var isError = false;
var msg = "";
switch (code)
{
case "BA":
await _rdlManager.SendMessage(barcode, false);
await _pdCommunicationsManager.SendPDUpdate("PICKING", barcode);
await _printerManager.ConvertImages(barcode);
msg = "BA" + barcode + "!0";
await _PlcMessages.SendMessage(msg);
break;
case "BB": //Printer 1
await _printerManager.PrintReceiptLabel(barcode);
break;
default:
msg = code + MiddlewareConsts.NullBarcodeString + "E0";
await _PlcMessages.SendMessage(msg);
break;
}
}
catch (Exception e)
{
var msg = "AA" + MiddlewareConsts.NullBarcodeString + "E0";
await _PlcMessages.SendMessage(msg);
}
}
}
}