我正在使用 async-await 方法设计一个异步 TCP 服务器,该方法利用具有以下功能的事件驱动的 .NET 环境:
- 请求和响应功能。
- 服务器端发起的事件。
这种服务器设计在异步等待方法方面是否正确?
下面的代码仅涵盖判断我是否缺少某些东西的基本功能。
服务器使用 COM 类型库,这是 PRMasterAutomation 类的来源。
public class AsyncServer {
private const int BufferSize = 4096;
private static bool ServerRunning = true;
private List<TcpClient> clients = new List<TcpClient>();
private PRMasterAutomation automation;
public AsyncServer()
{
InitializeComponent();
automation = new PRMasterAutomation();
automation.OnMonitoringEvent += automation_OnMonitoringEvent;
if (!automation.Login("ADMIN", ""))
return;
if (automation.GetPRMasterState() == PRMasterStateEnum.StateIdle)
automation.StartMonitoring();
var tcpServer = new TcpListener(IPAddress.Any, 9001);
tcpServer.Start();
ListenForClients(tcpServer);
}
private async void ListenForClients(TcpListener tcpServer)
{
while (ServerRunning)
{
TcpClient tcpClient = await tcpServer.AcceptTcpClientAsync();
clients.Add(tcpClient);
ProcessClient(tcpClient);
}
}
private async void ProcessClient(TcpClient tcpClient)
{
var stream = tcpClient.GetStream();
var buffer = new byte[BufferSize];
int amountRead;
string xml;
while (ServerRunning)
{
if ((amountRead = await stream.ReadAsync(buffer, 0, BufferSize)) > 0)
{
var message = Encoding.ASCII.GetString(buffer, 0, amountRead);
xml = "";
if (message.Equals("get_users"))
{
xml = automation.GetUsersXml();
}
else if (message.Equals("get_events"))
{
xml = automation.GetEventsHistoryXml("");
}
if (xml.Length > 0)
{
xml += "\r\n";
await stream.WriteAsync(Encoding.ASCII.GetBytes(xml), 0, xml.Length);
}
}
}
}
async void automation_OnMonitoringEvent(DateTime date, DateTime time, int networkID, int readerID, int userID, int groupID, int eventCode, int zoneID, int TandAID, string strEvent, string strAccessPoint, string strUserSource, string strGroup, string strNetwork, string strZone, string strTandAMode)
{
foreach (var c in clients)
{
if (c != null && c.Connected)
{
var stream = c.GetStream();
StringBuilder sb = new StringBuilder();
sb.Append(date.ToString() + ";" + time.ToString() + ";" + networkID.ToString() + ";" + userID.ToString() + "\r\n");
await stream.WriteAsync(Encoding.ASCII.GetBytes(sb.ToString()), 0, sb.Length);
}
}
}
}