提升异步休息客户端

时间:2016-09-22 20:39:55

标签: c++ multithreading asynchronous boost

我目前正在使用 boost :: asio :: io_service 处理异步休息客户端。 我正在努力使客户端成为更大程序的某种服务。 这个想法是客户端将独立于运行主程序的线程执行异步http请求到其他API。所以在客户端内部将是另一个等待请求发送的线程。 要将请求传递给客户端,我使用 io_service 和使用 io_service 初始化的 io_service :: work 。我几乎重用了本教程中给出的示例 - logger_service.hpp。 我的问题是,在示例中,他们将工作发布到服务,被调用的处理程序是一个简单的函数。在我的情况下,因为我正在进行这样的异步调用 (我已经完成了运行以下对象的所有实例的必要性,以及一些能够建立网络连接的方法):

boost::asio::io_service io_service_;
boost::asio::io_service::work work_(io_service_); //to prevent the io_service::run() to return when there is no more work to do
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket_(io_service_);

在主程序中,我正在进行以下调用:

client.Connect();
...
client.Send();
client.Send();
...

某些客户端的伪代码:

void MyClass::Send()
{
...
io_service_.post(boost::bind(&MyClass::AsyncSend, this);
...
}


void MyClass::AsyncSend()
{
...
boost::io_service::asio::async_write(socket, streamOutBuffer, boost::bind(&MyClass::handle_send, this)); 
...
}

void MyClass::handle_send()
{
boost::io_service::asio::async_read(socket, streamInBuffer, boost::bind(&MyClass::handle_read, this));
}

void MyClass::handle_read()
{
//    ....treatment for the received data...
   if(allDataIsReceived)    
      FireAnEvent(ReceivedData);
   else
    boost::io_service::asio::async_read(socket, streamInBuffer, boost::bind(&MyClass::handle_read, this));
}

正如文档中所述,“帖子”方法请求 io_service 调用指定的处理程序,立即返回。我的问题是,嵌套处理程序,例如 AsyncSend 中的:: handle_send,在 post()之后调用(当http响应准备就绪时)用过的?或者处理程序将以不同于post()调用顺序定义的顺序调用? 我问这个问题,因为当我只打电话一次 client-&gt; Send()时,客户端似乎“工作正常”。但是当我进行2次连续调用时,如上例所示,客户端无法完成第一次调用而不是执行第二次调用,并且在最后一些混乱执行之后,2次操作失败。

有没有办法做我正在描述的,在执行另一个之前执行整个异步链。

我希望,我对自己的描述很清楚:)

1 个答案:

答案 0 :(得分:0)

你好Blacktempel,

感谢您给出的评论和想法,但是我正在开发一个需要使用异步调用的项目。 事实上,因为我是Boost的新手,我的问题和我给出的例子在“handle_read”的部分中并不正确。功能。我现在在示例中添加几行,以便更清楚我在哪种情况下。 实际上在很多例子中,可能就是所有这些,谁正在处理主题如何创建异步客户端是非常基本的...他们只是展示如何链接不同的处理程序和数据处理时,&#39; handle_read& #39;被称为总是像&#34;在屏幕上打印一些数据&#34;在同一个读处理程序内部。我认为,与现实世界的问题相比,这是完全错误的! 没有人会打印数据并完成程序的执行......!通常一旦收到数据,就必须开始另一种治疗,例如FireAnEvent()。受到不好的例子的影响,我已经做了这个&#39; FireAnEvent&#39;在read处理程序里面,显然是完全错误的!这样做很糟糕,因为制作类似的东西,&#34; handle_read&#34;可能永远不会退出或退出太晚。如果此处理程序未完成,则io_service循环也不会完成。如果您的进一步处理需要再次向异步客户端执行某些操作,则会启动/重新启动(我不确定详细信息)io_service循环。就我而言,我正以这种方式对异步客户端进行多次调用。最后我看到了io_service是如何始终启动但从未结束的。即使整个治疗结束后,我也没有看到io_service停止。 所以最后我让我的异步客户端用handle_read中的接收数据填充一些全局变量,而不是直接调用另一个函数,如FireAnEvent。我在io_service.run()之后移动了这个函数(FireAnEvent)的调用。它起作用,因为在run()方法结束后我知道循环已经完成了! 我希望我的回答可以帮助人们:)