在初始套接字连接之后如何在TcpListener和TcpClient之间构建通信

时间:2017-11-10 12:50:36

标签: c# sockets asynchronous tcpclient tcplistener

所以对网络编程人员来说这可能很简单,但我对此有点困惑。让我试着问一下使用的例子。

假设我要创建一个聊天服务器,客户端可以使用用户名加入。没有帐户或密码。只是用户名。

我有一个运行的Echo Server示例,它使用异步调用,所以这一切都很好。现在我需要在客户端和服务器之间定义一些消息处理。

让我们说客户端现在连接,它想获得连接用户列表。我该怎么做呢?

我的想法是我创建了一个名为BeginGetConnectedUsers的函数,它将向服务器发送消息。然后服务器将回复一个用户列表,但由于我正在使用异步调用,我现在让我的接受代码查看该消息,并确定它是来自BeginGetConnectedUsers的回复,因此它将数据发送到EndGetConnectedUsers

但我不知道这是否是一个很好的方法来做这样的事情? 但是对于这种设计,我必须将每个BeginGet函数与EndGet函数配对。使用async await样式可以使这更具可读性,但是这可能不是更好。

我不知道在客户端和服务器必须开始交换所有有趣的数据时如何构建以下通信...

建议?看的地方?包含工作TCPLISTENER的所有谷歌搜索都会向我展示回声服务器的示例,我已经知道如何做到这一点。

1 个答案:

答案 0 :(得分:0)

这里有许多可行的实现。 我会实现策略模式或控制器模式。其他选项包括状态机(确定性自动机)或甚至是简单大的开关盒。

所以基本上你只有一个函数来接收来自网络的消息。 所有消息实现相同的接口可能是

IMessage<T>
{
    string Type {get;set;}
    T Data {get;set;}
}

因此,当您收到消息时,使用Type属性将T Data路由到您想要的实际方法。 在使用控制器的简单实现中,您可以使用指示要管理的消息类型的属性来分配控制器方法:

class Controller
{
    [Messagetype("GetConnectedUsersResponse")]
    Response GetConnectedUsers(IEnumerable<User> users)
    {
        //...
    }

    [Messagetype("AnothermessageType")]
    Response OtherStuffToDo(....)
    {
        //...
    }
}

当您收到消息时,通过使用一些简单的反射,您可以动态调用具有匹配消息类型属性的attibute的方法。

如果你不喜欢反射另一种选择(在许多其他docens中)是使用策略模式 因此,您可以在IoC容器中按键注册一些消息处理程序。 所有hadlers实现一个函数让我们说

interface MessageHandler<T>
{
    Response Handle(T Data);
}

当您收到消息时,您只需使用您最喜欢的IoC容器解析处理程序(按名称解析最近被视为atipattern,所以请用一点盐来处理)

var handler = container.resolve(message.Type);
var response = handler.handle(message.Data);

在这两个实现中,您应该定义您的响应方式(如果这样做)并调整“响应”返回类型(可能您没有响应,因此它是无效的)