Вот моя реализация:
- Клиент A отправит сообщение для клиента B
- Сервер обработает сообщение с помощью
async_read
нужного количества данных и будет ждать новых данных отКлиент A (для того, чтобы не блокировать Клиента A) - После этого Сервер обработает информацию (возможно, выполнит запрос mysql), а затем отправит сообщение Клиенту B с помощью
async_write
.
Проблема в том, что если клиент A действительно быстро отправляет сообщение, async_writes
будет чередоваться до вызова предыдущего обработчика async_write.
Есть ли простой способ избежать этой проблемы?
EDIT1: Если клиент C отправляет сообщение клиенту B сразу после клиента A, должна появиться та же проблема ...
РЕДАКТИРОВАТЬ 2: Это будет работать?потому что, кажется, блокирует, я не знаю, где ...
namespace structure {
class User {
public:
User(boost::asio::io_service& io_service, boost::asio::ssl::context& context) :
m_socket(io_service, context), m_strand(io_service), is_writing(false) {}
ssl_socket& getSocket() {
return m_socket;
}
boost::asio::strand getStrand() {
return m_strand;
}
void push(std::string str) {
m_strand.post(boost::bind(&structure::User::strand_push, this, str));
}
void strand_push(std::string str) {
std::cout << "pushing: " << boost::this_thread::get_id() << std::endl;
m_queue.push(str);
if (!is_writing) {
write();
std::cout << "going to write" << std::endl;
}
std::cout << "Already writing" << std::endl;
}
void write() {
std::cout << "writing" << std::endl;
is_writing = true;
std::string str = m_queue.front();
boost::asio::async_write(m_socket,
boost::asio::buffer(str.c_str(), str.size()),
boost::bind(&structure::User::sent, this)
);
}
void sent() {
std::cout << "sent" << std::endl;
m_queue.pop();
if (!m_queue.empty()) {
write();
return;
}
else
is_writing = false;
std::cout << "done sent" << std::endl;
}
private:
ssl_socket m_socket;
boost::asio::strand m_strand;
std::queue<std::string> m_queue;
bool is_writing;
};
}
#endif