で、私は以下のことを行いASIOとクライアントを記述しようとしていますについて混乱:ブースト:: ASIO ::降伏オーダー実行の同じ鎖
- がサーバーに接続します。
- のデータを読み取ろうとすると、がサーバーに接続されています。
私が見ている問題は、操作が順番に実行されていないように思われることです。ここでは、コードは次のとおりです。
std::future<NetMessage> Cliente::asyncConnectTo(std::string const & hostname,
int port,
std::string const & name) {
using namespace std::literals;
boost::asio::spawn
(strand_,
[this, name, port, hostname](boost::asio::yield_context yield) mutable {
i_->playerLog->trace() << name << " connecting to " << hostname << ':'
<< port;
Guinyote::Utils::connectWith
(*this, std::move(hostname), port,
std::move(name), yield);
i_->playerLog->info() << "Connected to server.";
});
runthread_ = std::thread([&] {
try {
i_->playerLog->info() << "Starting...";
this->service_.run();
}
catch (std::exception & e) {
std::cout << e.what() << std::endl;
}
});
return this->asyncReceiveMessage(); //This function spawns another coroutine through the same strand_ object.
}
機能this->asyncReceiveMessage()
は、サーバーが接続した後に送り返すメッセージ受け取ることが予想されます。
std::future<NetMessage> Cliente::asyncReceiveMessage() {
namespace ba = boost::asio;
std::promise<NetMessage> prom;
std::future<NetMessage> message = prom.get_future();
ba::spawn
(strand_,
[this, p = std::move(prom)](boost::asio::yield_context yield) mutable {
i_->playerLog->trace("waiting to read message from server socket...");
boost::system::error_code ec{};
boost::int64_t messageSize{};
ba::async_read(
socket_,
ba::buffer(&messageSize, sizeof(boost::int64_t)),
yield);
i_->playerLog->trace() << "Client: Received message of "
<< messageSize << " bytes. Reading message...";
std::vector<char> serverMessageData(messageSize);
ba::async_read
(socket_,
ba::buffer(serverMessageData),
yield);
using namespace boost::iostreams;
basic_array_source<char> input_source(&serverMessageData[0], serverMessageData.size());
stream<basic_array_source<char>> stream(input_source);
boost::archive::binary_iarchive archive(stream);
Utils::MensajeRed msg;
archive >> msg;
i_->playerLog->trace() << "NetMessage correctly read.";
p.set_value(std::move(msg));
});
return message;
}
私のログファイルでは、私はクライアント側で次のようになっていました:
[clientLog] [info] Client: Starting...
[clientLog] [trace] User1234 connecting to localhost:10004
[clientLog] [trace] waiting to read message from server socket...
しかし、私はそのログの3行目は[clientLog] [info] Connected to server.
後に来ることを期待するので、私の予想は以下の通りである:
[clientLog] [info] Client: Starting...
[clientLog] [trace] User1234 connecting to localhost:10004
[clientLog] [info] Connected to server.
[clientLog] [trace] waiting to read message from server socket...
すなわち、「サーバに接続された」常に「...サーバソケットからのメッセージを読むのを待っている」前が起こるはずです。
何が起こっているのか分かりませんか?私はstrand_
が実行の順序を保証すると思ったが、何か誤解しているようだ。私が望む効果を得るための正しい解決策は何ですか?
これは同じですが、私は適切な解決策を見ません。実際には「手で扱う」のようなものがあります:http://stackoverflow.com/questions/19946555/boostio-service-how-to-guarantee-handler-execution-sequence –