Я хотел написать оболочку над ASIO повышения для реализации клиент/сервер tcp. Интерфейс boost ASIO действительно хорош, но причиной необходимости обертки является возможность заменить цикл событий чем-то другим. В нашем usecase нам нужно просто вызвать одну и ту же функцию обработчика для каждого асинхронного чтения, приложению не нужно передавать обработчик для каждого вызова asyncRead. Таким образом, это помогает зарегистрировать обработчик на один раз. Один из способов, которым я пробовал, - этоBoost ASIO с CRTP или PBCP или утиная печать
template <class Connection>
struct TCPClient { // implements the interface with ASIO
Connection *_connection;
void setConnection (Connection *connection)
{
_connection = connection;
}
void asyncRead()
{
_socket.async_read_some(boost::asio::null_buffers(),
[this] (ErrorType err, unsigned a) {
if (_connection) _connection->handleRead(err);
if (!err) asyncRead();
});
}
};
я мог бы сделать подобное с CRTP
class MyConnection : public TCPClient<MyConnection> {
void readHandler (TCPClient::ErrType err)
{
}
};
А в классе TcpClient asyncRead будет
void asyncRead()
{
_socket.async_read_some(boost::asio::null_buffers(),
[this] (ErrorType err, unsigned a) {
((Connection *)this)->handleRead(err);
if (!err) asyncRead();
});
}
Это в случае полезно, поскольку время жизни TcpClient и подключение такое же.
Или PBCP
template <typename Connection>
class TCPClient : public Connection {
void asyncRead()
{
_socket.async_read_some(boost::asio::null_buffers(),
[this] (ErrorType err, unsigned a) {
Connection::handleRead(err);
if (!err) asyncRead();
});
}
};
Я не думаю, что на самом деле есть IS-A отношение ч/б TcpClient и подключение. Я смущен, если какая-либо из этих схем хороша. (Также мне интересно, почему ASIO не имеет схемы, где кеширует обработчик один раз и вызывает его каждый раз. По крайней мере, в случае чтения Async обычно нет контекста, который нужно вернуть. В нашем случае скорость чтения сообщений является самой большой проблемой и Boost ASIO копирует обработчик чтения каждый раз + распределение памяти для хранения действительно плохо. Поэтому, основываясь на результатах тестирования, возможно, придется изменить цикл событий на что-то пользовательское)
Asio предоставляет крючки для управления памятью обработчика (см. [Распределение пользовательской памяти] (http://www.boost.org/doc/libs/1_63_0/doc/html/boost_asio.html#boost_asio.overview.core.allocation]). Asio разработан, чтобы быть основой для дальнейших абстракций, а парадигма _one-callback-for-operation_ упрощает реализацию других парадигм. Прежде чем писать специальный цикл событий, я настоятельно рекомендую рассмотреть [libuv] (https://github.com/libuv/libuv), который поддерживает тот же обратный вызов, который вызывается в любое время, когда данные становятся доступными. –
Я никогда не слышал о PBCP. Что это? Google очень уверенно ничего не знает об этом. (Если бы я должен был расшифровать аббревиатуру от кода, я бы предположил «Parameterized Base Class Pattern»? Мы бы назвали это Mixin) – sehe
@sehe. Да, это он. – MGH