boost asio async_write: как не чередовать вызовы async_write?

Вот моя реализация:

  • Клиент A отправляет сообщение для клиента B
  • Сервер обработать сообщение async_read нужным объемом данных и будет ждать новых данных от клиента A (чтобы не блокировать клиента A)
  • После этого сервер обработает информацию (возможно выполните запрос mysql ), а затем отправьте сообщение клиенту B с помощью async_write .

Проблема в том, что если клиент A отправляет сообщение очень быстро, async_writes будет interleave перед вызовом предыдущего обработчика async_write.

Есть ли простой способ избежать этой проблемы?

РЕДАКТИРОВАТЬ 1: Если клиент C отправляет сообщение клиенту B сразу после клиента A, s Должна появиться проблема ...

РЕДАКТИРОВАТЬ 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
26
задан TheSquad 13 October 2011 в 16:52
поделиться