我有一个 AsyncSocketServer 类来管理TCP套接字服务器。这个消息从其用户异步接收消息,其中每个"用户会话"在一个单独的线程中进行管理,并在新消息到达时引发一个名为 NewData 的事件
while ((bytesRead = await state.workSocket.ReceiveTask (state.buffer)) > 0)
{
string message = state.sb.Append (Encoding.UTF8.GetString (state.buffer, 0, bytesRead));
var targetEvent = NewData;
if (targetEvent != null)
{
NewDataEventArgs e = new NewDataEventArgs ();
e.dataReceived += message;
targetEvent (this,e);
}
}
请注意 " ReceiveTask" 是我用来包装APM模型的扩展方法。
我想要解决的问题是每次我收到来自任何用户的消息时,应该将消息重新发送到每个连接的套接字(包括发送消息的套接字)
我遇到过两个解决方案,但我不能说哪一个更好。
第一个解决方案:将workSockets存储到Dictionary中,并将eventdanler循环通过此循环,同时将消息发送到存储在其中的套接字。
我在这里做的是在调用其构造函数时将我的AsyncSocketServer类订阅到事件NewData
public AsyncSocketServer ()
{
this.NewData += new EventHandler<NewDataEventArgs> (this.BroadCastMessage);
}
BroadCastMessage是我的AsynSocketServer类中的异步事件处理程序。
private async void BroadCastMessage(object sender, NewDataEventArgs e)
{
List<Task<int>> tasks = new List<Task<int>> ();
byte[] databytes = Encoding.ASCII.GetBytes(e.dataReceived);
lock (lock_AddressBook)
{
foreach (string key in AddressBook.Keys)
{
tasks.Add (AddressBook[key].SendTask (databytes));
}
}
await Task.WhenAll(tasks.ToArray());
}
正如您所看到的,此方法循环执行一个维护的Dictionary,该Dictionary包含执行异步发送操作时的所有workSockets。
第二个解决方案:将workSockets订阅到活动
我在这里做的是,一旦建立连接并在进入while循环之前,我创建一个本地事件处理程序并将其附加到事件。
Action<object,NewDataEventArgs> onnewdata = async (sender, e) =>
{
await handler.SendTask (Encoding.ASCII.GetBytes(e.dataReceived));
};
this.NewData += onnewdata;
这是我已经开发的两种解决方案,所以我想知道哪一个更好,听听有利有关或者你建议的任何改进都是受欢迎的。