Я реализую протокол RTMP, используя boost::asio::socket
.
После async_accept протокол требует трехэтапного рукопожатия.См. Код ниже:
.
.
.
void RtmpServer::StartAsyncAccept()
{
// Create a new connection
nextConn = RtmpConnection::Create(this, ios);
// FIXME: shall we use async or blocking accept???
acceptor.async_accept
(
nextConn->GetSocket(),
boost::bind
(
&RtmpServer::HandleAsyncAccept,
this,
boost::asio::placeholders::error
)
);
}
.
.
.
void RtmpServer::HandleAsyncAccept(const boost::system::error_code& ec)
{
if (!ec)
{
if (nextConn->StartHandshake())
{
// Push the current connection to the queue
AddConnection(nextConn);
boost::array<char, 0> dummyBuffer;
nextConn->GetSocket().async_read_some
(
// TODO: use a strand for thread-safety.
boost::asio::buffer(dummyBuffer), // FIXME: Why boost::asio::null_buffers() not working?
boost::bind
(
&RtmpConnection::HandleData,
nextConn,
boost::asio::placeholders::error
)
);
}
}
// Start to accept the next connection
StartAsyncAccept();
}
RtmpConnection::StartHandshake
вернет true, если рукопожатие выполнено успешно (тогда будет вызвано RtmpConnection :: HandleData), иначе false (соединение прервано, еще не обработано).
Существует три основных шага для рукопожатия, каждый из которых включает в себя сообщения Cx и Sx, то есть C{0,1,2}
, S{0,1,2}
.
Базовое рукопожатие ДОЛЖНО следовать:
// HANDSHAKE PROTOCOL
// Handshake Sequence:
// The handshake begins with the client sending the C0 and C1 chunks.
//
// The client MUST wait until S1 has been received before sending C2.
// The client MUST wait until S2 has been received before sending any
// other data.
//
// The server MUST wait until C0 has been received before sending S0 and
// S1, and MAY wait until after C1 as well. The server MUST wait until
// C1 has been received before sending S2. The server MUST wait until C2
// has been received before sending any other data.
Как вы могли заметить, (как обычно) рукопожатие требует ожидания.Например,
Сервер ДОЛЖЕН подождать, пока утилита C0 была получена перед отправкой S0.В нашем случае C0 содержит только однобайтовое целое число версии, и сервер должен проверить, является ли версия действительной или нет, затем отправить S0 клиенту.
И так далее, аналогично C1 / S1,C2 / S2 (но немного по-другому).
У меня вопрос, должен ли я использовать блокировку чтения / записи для этого рукопожатия или асинхронный?
В настоящее время я использую блокировку чтения / записи, котораяпроще в реализации.
Однако я много гуглил, обнаруживая, что многие парни предлагают асинхронное чтение / запись, потому что они имеют лучшую производительность и большую гибкость.
Я спрашиваючто я должен сделать, используя асинхронное чтение / запись сокетов?Должен ли я создать кучу обработчиков для этих 3 основных шагов?или любые другие лучшие предложения.
Пример псевдокода будет оценен.