Hi,
Thank you for your response. I will take a look at the transport policies as you mention. I just feel perhaps I did not get across our situation very well (mostly due to us borrowing the name socket to mean something slightly different than socket... thus my quote marks in the first post..)
To clarify I would like to add more specific details.
We are porting a C++ server that used to support Flash-clients to instead support HTML-clients using websocket. The server is fully async and is built using boost::asio, we are very happy to have found websocketpp.
We will only be interested in the async + tls option.
In our existing codebase (the one that talks to Flash-clients) we have separated the network code into two kind of objects, the IConnection that handles queing for sends and have a circular read buffer (we have a header with size, and then a binary body containing a zlib-compressed google protobuf message). It also handles some flash-idiosyncracies (with a <policy-file-request> sometime arriving before the TLS handshake..).
The interface to this object looks like this:
class IConnection
{
public:
virtual ~IConnection() {}
virtual bool isNullConnection() const = 0;
virtual void startRead(boost::weak_ptr<IConnectionHandler> handler) = 0;
virtual void send(const boost::shared_ptr<Message>& msg) = 0;
virtual void disconnect() = 0; // This operation is always asynchronous, ie the handler onDisconnect is posted on the io
virtual bool isConnected() const = 0;
virtual std::string remoteIp() const = 0;
};
with startRead(...) and send(...) being the most important methods. This interface may look very similiar to your websocketpp connection but since we put a few higher level things in there to (our own binary framing + zlib + protobuf), the minimal change to our (by now stable and proven) codebase would be to only change the lower level constuct. The "socket". This is really a very thing wrapper around boost::asios async methods and we put it there to have a runtime polymorphism vs plain sockets and SSL sockets (and also to enable unittesting).
The socket have this interface:
class ISocket
{
public:
virtual ~ISocket() {}
virtual std::string remoteIp() const = 0;
virtual void asyncWrite(
const std::vector<unsigned char>& buf,
int noOfbytesToSend,
boost::function<void (const boost::system::error_code& error, size_t bytesTransferred)> callback) = 0;
virtual void asyncReadSome(
MutableBufferSequenceAdapter& buf,
boost::function<void (const boost::system::error_code& error, size_t bytesTransferred)> callback) = 0;
virtual void close() = 0;
virtual boost::asio::io_service& getIoService() = 0;
};
with asyncWrite and asyncReadSome beeing the important ones. MutableBufferSequenceAdapter is a helper that maps boost::asio buffers to google protobufs ZeroCopy buffer.
Now I rephrase my question to: Do you think it is a good idea to make a new implementation of our ISocket that wraps websocketpp connection or do we need to attack this on the level of our IConnection. And if we implement the ISocket, what construct should we use (connection seems to high level as it adds queuing and do not provide a callback from its send method).
You probably answered this in your first response and I just have to read up on it and think :)
I just wanted to post this more detailed explanation of our problem in case it helps.
Regards,
Jonas