我想知道存在一种允许使用boost::asio
在c ++中实现以下内容的技术:
NetworkService
允许向连接的端点发送消息,这些端点通常会发送一条响应消息,该消息被委派给观察者(通常是发起请求的GUI窗口)。
(简化代码):
void NetworkService::send_message(std::string id, message& msg)
{
std::shared_ptr<TcpStream> stream = connectionManager_.findStream(id);
io_service_.post([this, msg, stream]() { stream->deliver(msg); });
}
所以,从我的MainWindow类开始,我正在使用这样的服务:
// on button click:
message msg(...);
networkService_->send_message(strEndpointIdentity, msg);
在事件方法中,我最终会收到回复:
void MainGui::onMessageReceived(std::shared_ptr<message> msg)
{
}
这确实有效,但是,我想知道是否可以以我可以发送消息的方式实现它,并提供lambda函数作为回调,以便当它收到相应消息类型的响应时,它被直接调用:
( “伪”):
message request;
networkService_->send_message(endpointAddress, request,
[response]{
txtOutput.text = response.data()
});
这甚至可能吗?
附加代码:
TcpStream类:
void TcpStream::readHeader()
{
auto self(shared_from_this());
asio::async_read(socket_, asio::buffer(read_msg_.header(), message::header_length), [this, self](asio::error_code ec, std::size_t len)
{
if (!ec)
{
read_msg_.resize();
readBody();
}
});
}
void TcpStream::readBody()
{
auto self(shared_from_this());
asio::async_read(socket_, asio::buffer(read_msg_.data(), read_msg_.payload_size()), [this, self](asio::error_code ec, std::size_t)
{
if (!ec)
{
auto msg = std::make_shared<message>(std::move(read_msg_));
if (msg->message_type() == 1) // initMessage
{
this->identity_ = std::string(read_msg_.data());
connectionManager_->join(shared_from_this());
}else{
// delegate message
std::for_each(m_listeners.begin(), m_listeners.end(), [&](IStreamListener *l) {l->onMessageReceived(msg); });
}
readHeader(); // loop
}
});
}
void TcpStream::deliver(const message& msg)
{
bool write_in_progress = !write_msgs_.empty();
write_msgs_.push_back(msg);
if (!write_in_progress)
write();
}
void TcpStream::write()
{
auto self(shared_from_this());
asio::async_write(socket_, asio::buffer(write_msgs_.front().header(),message::header_length),[this, self](asio::error_code ec, std::size_t)
{
if (!ec)
{
asio::async_write(socket_, asio::buffer(write_msgs_.front().data(), write_msgs_.front().payload_size()),
[this, self](asio::error_code ec, std::size_t)
{
if (!ec)
{
write_msgs_.pop_front();
if (!write_msgs_.empty())
{
write();
}
}
});
}
});
}