I have client/server applications and a very simple protocol for communication. More precisely, it's a set of commands a server sends and a set of requests a client can make.
The idea is as follows:
When a command is made by the server, a client has to execute it. When a request is made, server checks permissions and if everything is ok it grants the request.
The application is written in C++ and I got slightly stuck designing the architecture for this sort of communication protocol. Assuming that command/request is a tab-delimited string with first parameter being the name of the message, I was planning to make a MessageManager
class which would store all messages in a hash-table and retrieve them when necessary. The problem here is this:
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 ¶ms ) const = 0;
protected:
virtual void checkPermissions( const Client &c, const ArgArray ¶ms ) const = 0;
#endif
};
Because different messages can take different arguments to be constructed I can't really create a complete interface. For example, some messages might need a simple string to be constructed, whereas others might need some numeric data. This complicates things and makes the design a bit untidy... I.e. I have to get round the problem by ommitting make()
from interface definition and simply add different make()
for each Request I make. Also, if I wish to store pointers to different Requests in one container I cannot use dynamic_cast
because Request
is not a polymorphic type. An obvious (untidy) solution would use make( int n, ... )
definition and use stdarg.h
to extract different arguments but I consider this to be unsafe and confusing for the programmer.
There is obviously a design flaw in my idea. I already have a solution in mind but I am just wondering, how would people at SO tackle this problem? What sort of Object architecture would you use? Is there a simpler approach that could solve this problem? There aren't any specific requirements to this except to keep it as simple as possible and to keep the actual protocol as it is (tab-delimited strings with first parameter indicating which message it is).