【问题标题】:Designing a class architecture for network messages为网络消息设计类架构
【发布时间】:2009-07-06 23:32:27
【问题描述】:

我有客户端/服务器应用程序和一个非常简单的通信协议。更准确地说,它是服务器发送的一组命令和客户端可以发出的一组请求。

思路如下:

当服务器发出命令时,客户端必须执行它。 发出请求时,服务器会检查权限,如果一切正常,它就会授予请求。

应用程序是用 C++ 编写的,我在为这种通信协议设计架构时有点卡住了。假设命令/请求是一个制表符分隔的字符串,第一个参数是消息的名称,我打算创建一个 MessageManager 类,它将所有消息存储在哈希表中并在必要时检索它们。这里的问题是:

typedef std::vector< std::string > ArgArray;
class Request : public Message
{
public:
   Request( const char *name ) : Message( name ) { }
#ifdef CLIENT
   /** problem here **/
   virtual void make( ... ) = 0;
#elif defined SERVER
   virtual void grant( const Client &c, const ArgArray &params ) const = 0;
protected:
   virtual void checkPermissions( const Client &c, const ArgArray &params ) const = 0;
#endif
};

因为不同的消息可以采用不同的参数来构造,所以我不能真正创建一个完整的接口。例如,某些消息可能需要构造一个简单的字符串,而其他消息可能需要一些数字数据。这使事情复杂化并使设计有点凌乱......即我必须通过从接口定义中省略make() 来解决这个问题,并为我提出的每个请求简单地添加不同的make()。另外,如果我希望将指向不同请求的指针存储在一个容器中,我不能使用dynamic_cast,因为Request 不是多态类型。一个明显(不整洁)的解决方案是使用make( int n, ... ) 定义并使用stdarg.h 来提取不同的参数,但我认为这对程序员来说是不安全且令人困惑的。

我的想法显然存在设计缺陷。我已经有了一个解决方案,但我只是想知道,SO 的人们将如何解决这个问题?你会使用什么样的对象架构?有没有更简单的方法可以解决这个问题?对此没有任何特定要求,只是要使其尽可能简单并保持实际协议不变(制表符分隔的字符串,第一个参数指示它是哪条消息)。

【问题讨论】:

    标签: c++ oop networking client-server


    【解决方案1】:

    我认为您设计中的问题是您试图将太多功能塞进一个类中。例如,关于构造/解析消息以包含数字数据或字符串(即序列化)的部分应该与底层连接逻辑分开。

    如果允许您使用其他库,请查看 Boost.Serialization。 Boost 也有一个非常好的网络库,称为ASIO。即使您不允许使用 boost,您也应该咨询他们的库设计。

    【讨论】:

    • 这就是我想到的解决方案。将实际解析与执行分开。 IE。对于每条消息都有一个可序列化的结构,这些消息被创建并进一步传递。然后我们可以创建不带参数的虚函数make(),因为它们都是结构的成员。 :)
    • 对不起。当我写make() 时,我犯了一个错误。我的意思是执行请求/命令的执行函数。
    • 要考虑的另一件事是使用访问者模式来解析和序列化代码。当您有一组需要处理的预定义消息类时,它会非常有用。
    【解决方案2】:

    是的,您说“命令/请求是制表符分隔的字符串”:正如 kuoson 所说,“不同的消息可以采用不同的参数”这不是真的......相反,所有消息都是从制表符分隔的字符串。

    【讨论】:

    • 我的意思是,当您创建消息时,您可能需要序列化一些数据。 IE。如果我遵循当前的实现,我可能会有类似:make( int x, int y, int z ) 这将创建一条消息并发送超过 3 个整数。然后接收者得到制表符分隔的字符串。 :)
    【解决方案3】:
    猜你喜欢
    • 2013-11-29
    • 2016-05-11
    • 1970-01-01
    • 1970-01-01
    • 2020-01-29
    • 2020-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多