C#TCP套接字服务器:向所有连接的客户端广播收到的消息

时间:2015-04-02 14:05:29

标签: c# multithreading sockets tcp

我有一个 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;

这是我已经开发的两种解决方案,所以我想知道哪一个更好,听听有利有关或者你建议的任何改进都是受欢迎的。

0 个答案:

没有答案