我设计使用异步等待的方法,利用事件驱动的.NET环境中,具有以下特点的异步TCP服务器:简单的异步等待TCP服务器的设计
- 请求和响应功能。
- 服务器端发起的事件。
这种服务器设计在异步等待方法方面是否正确?
下面的代码仅涵盖了判断我是否缺少某些东西的基本功能。
服务器使用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);
}
}
}
}
实际上它接受下一个客户端,因为调用'amountRead = await stream.ReadAsync(buffer,0,BufferSize)'不会阻塞并允许继续接受客户端。 – koszyczeq