यहाँ मेरी कार्यान्वयन है:बूस्ट asio async_write: async_write कॉल को अंतःस्थापित नहीं करना है?
- ग्राहक एक संदेश ग्राहक बी के लिए
- सर्वर संदेश प्रक्रिया
async_read
से सही मात्रा में डेटा की (भेजने और ब्लॉक करने के लिए नहीं आदेश में ग्राहक एक से नए डेटा के लिए इंतजार करेंगे क्लाइंट ए) - बाद में सर्वर जानकारी को संसाधित करेगा (शायद एक mysql क्वेरी करें) और फिर
async_write
के साथ क्लाइंट बी को संदेश भेजें।
समस्या यह है कि यदि क्लाइंट ए संदेश भेजता है तो वास्तव में तेज़, async_writes
पिछले async_write हैंडलर से पहले इंटरलीव करेगा।
क्या इस समस्या से बचने के लिए कोई आसान तरीका है?
संपादित करें 1: एक ग्राहक सी बस ग्राहक एक के बाद, एक ही मुद्दा दिखाई देनी चाहिए ग्राहक बी को एक संदेश भेजता है ...
संपादित करें 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
ध्यान दें कि async लिखने बहुत कम मूल्यवान से async पढ़ा है। अधिकांश लिखने वस्तुतः तत्काल होते हैं क्योंकि ओएस स्थानीय रूप से डेटा को बफर करेगा। दूसरी तरफ पढ़ता है रिमोट साइड के लिए इंतजार कर रहा है, और आप स्थानीय रूप से इसके बारे में कुछ भी नहीं कर सकते हैं। सिंक्रोनस लेखन इसलिए अनुक्रमण को कार्यान्वित करने का एक व्यवहार्य तरीका है। यह डेटा स्वामित्व के मुद्दे को भी हल करता है - ऊपर दिया गया कोड गलत है क्योंकि 'लिखना ('' रिटर्न' होता है, जो 'बूस्ट :: asio_async_write()' बफर तक पहुंचने से पहले हो सकता है। – MSalters