处理客户端/服务器消息?

时间:2012-10-07 16:18:41

标签: c# .net-4.0 client-server ooad

从我的客户端/服务器收到序列化数据,一旦数据被反序列化,它就进入命令处理程序,其中receivedData.ActionClientMessage

Command._handlers[receivedData.Action].Handle(receivedData.Profile);

命令处理程序将计算客户端消息并返回应该提供给客户端的响应。

我有一个客户端消息的枚举如下:

public enum ClientMessage
{
    INIT = 1,
    NEW_PROFILE,
    UPDATE_PROFILE_EMAIL,
    UPDATE_PROFILE_PASSWORD,
    UPDATE_PROFILE_PHONE,
    UPDATE_PROFILE_DATE,
    UPDATE_PROFILE_SECRET_ANSWER,
    UPDATE_PROFILE_POSTAL_CODE,
    UPDATE_SUCCESS,
    PING,
    PONG,
    QUIT
}

我遇到的困难是如何编写所有动作,例如:

  • 我应该为客户端发送的内容和服务器应该回复的内容分别设置枚举吗?
  • 或者我应该对所有邮件都有一个枚举,并按要求关注它?
  • 或者我该如何定义消息并进行处理呢?

这是我的服务器/客户端目前只是为了给您提供更好的视图:

  1. 服务器启动
  2. 客户端连接
  3. 客户端将auth发送到服务器
  4. 服务器验证客户端并发送已连接的批准消息
  5. 客户端将从那里开始向服务器发送和更新配置文件
  6. 这仅仅是一个例子。

    IPacketHandler

    public interface IPacketHandler
    {
        MyCommunicationData Handle(ProfileData profile);
    }
    

    命令

    public class Command
    {
        public static Dictionary<ClientMessage, IPacketHandler> _handlers = new Dictionary<ClientMessage, IPacketHandler>()
        {
            {ClientMessage.INIT, new Init()},
            {ClientMessage.NEW_PROFILE, new NewProfile()},
            {ClientMessage.UPDATE_PROFILE_EMAIL, new UpdateEmail()},
            {ClientMessage.UPDATE_PROFILE_PASSWORD, new UpdatePassword()},
            {ClientMessage.UPDATE_PROFILE_PHONE, new UpdatePhone()},
            {ClientMessage.UPDATE_PROFILE_DATE, new UpdateDate()},
            {ClientMessage.UPDATE_PROFILE_SECRET_ANSWER, new UpdateSecretAnswer()},
            {ClientMessage.UPDATE_PROFILE_POSTAL_CODE, new UpdatePostalCode()},
            {ClientMessage.UPDATE_SUCCESS, new Success()},
            {ClientMessage.PING, new Ping()},
            {ClientMessage.PONG, new Pong()},
            {ClientMessage.QUIT, new Quit()},
        };
    }
    

    INIT的例子

    public class Init : IPacketHandler
    {
        public MyCommunicationData Handle(ProfileData profile)
        {
            // Some verification to auth the client here 
            // bla bla
            // return response
            return new MyCommunicationData() { Action = ClientMessage.CONNECTED };
        }
    }
    
    PS:如果我的标题已经关闭,你有更好的建议让我知道,或者如果你可以继续更新它,我不知道如何用英语描述。

2 个答案:

答案 0 :(得分:1)

如果您的问题是关于如何按照我的理解设计类和交互,那么我会 - 并且它完全依赖于您的应用程序的细节 - 将这个大的Enumerations类型分成单独的,更小的类型,更具描述性他们做了什么,以及你的意图,例如,ProfileActionActionResultPingStatus等。然后当你使用这些枚举时,你要确保你得到编译时间检查你是否正确地做了,否则,你所做的几乎就像传递字符串一样。

它还与在OO设计中坚持单一责任原则有关:一个对象应该承担单一责任。你现在的枚举有不止一个责任。

对于这些问题,我发现查看.NET框架的作用很有帮助:例如,查看Ping class以及它如何使用PingStatus枚举和其他枚举。

答案 1 :(得分:0)

不确定我是否会使用枚举。它们在代码中很好,暴露为传达的价值,它们远不如伟大。

对我来说,每个消息都有一个不同的类,而不是一个带有神属性的消息。