简体   繁体   English

提升异步其他客户端

[英]boost async rest client

I currently working on a async rest client using boost::asio::io_service . 我目前正在使用boost :: asio :: io_service在异步REST客户端上工作。 I am trying to make the client as a some kind of service for a bigger program. 我正在尝试使客户成为大型程序的一种服务。 The idea is that the client will execute async http requests to a rest API, independently from the thread running the main program. 这个想法是,客户端将独立于运行主程序的线程执行对其余API的异步http请求。 So inside in the client will be another thread waiting for a request to send. 因此,客户端内部将是另一个线程,等待发送请求。 To pass the requests to the client I am using a io_service and io_service::work initialized with the io_service . 要通过我使用与io_service对象初始化一个io_service对象io_service对象::工作的要求给客户端。 I almost reused the example given on this tutorial - logger_service.hpp . 我几乎重用了本教程中给出的示例logger_service.hpp My problem is that when in the example they post a work to the service, the called handler is a simple function. 我的问题是,在示例中,他们将工作发布到服务时,被调用的处理程序是一个简单的函数。 In my case as I am making async calls like this (I have done the necessary to run all the instancies of the following objects and some more in a way to be able to establish the network connection): 以我为例,我正在进行这样的异步调用(我已经完成了运行以下对象的所有实例的必要工作,并以能够建立网络连接的方式进行了一些其他工作):

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_);

In the main program I am doing the following calls: 在主程序中,我正在执行以下调用:

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

Some client's pseudo code: 一些客户的伪代码:

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));
}

As it is described in the documentation the ' post ' method requests the io_service to invoke the given handler and return immediately . 如文档中所述,“ post ”方法请求io_service调用给定的处理程序并立即返回 My question is, will be the nested handlers, for example the ::handle_send in the AsyncSend , called just after (when the http response is ready) when post() is used? 我的问题是,将使用嵌套的处理程序,例如AsyncSend中的:: handle_send,何时使用post()时(在http响应就绪时)调用? Or the handlers will be called in another order different from the one defined by the order of post() calls ? 还是将以与post()调用的顺序定义的顺序不同的另一顺序调用处理程序? I am asking this question because when I call only once client->Send() the client seems to "work fine". 我问这个问题是因为当我只调用一次client-> Send()时 ,客户端似乎“工作正常”。 But when I make 2 consecutive calls, as in the example above, the client cannot finish the first call and than goes to execute the second one and after some chaotic executions at the end the 2 operations fail. 但是,如上例所示,当我连续进行2次调用时,客户端无法完成第一个调用,然后去执行第二个调用,并且最后经过一些混乱的执行之后,这2个操作失败了。

Is there any way to do what I'm describing execute the whole async chain before the execution of another one. 有什么方法可以执行我正在描述的操作,然后再执行另一个异步链。

I hope, I am clear enough with my description :) 我希望我的描述足够清楚:)

hello Blacktempel, 你好Blacktempel,

Thank you for the given comment and the idea but however I am working on a project which demands using asynchronous calls. 感谢您的评论和想法,但是我正在开发一个需要使用异步调用的项目。 In fact, as I am newbie with Boost my question and the example I gave weren't right in the part of the 'handle_read' function. 实际上,由于我是Boost的新手,所以我的问题和给出的示例在'handle_read'函数的一部分中是不正确的。 I add now a few lines in the example in a way to be more clear in what situation I am (was). 我现在在示例中添加几行,以便更清楚地了解我所处的状态。 In fact in many examples, may be all of them, who are treating the theme how to create an async client are very basic... All they just show how to chain the different handlers and the data treatment when the 'handle_read' is called is always something like "print some data on the screen" inside of this same read handler. 实际上,在许多示例中,可能都是所有人,他们都在讨论如何创建异步客户端的主题,这是非常基本的……所有这些只是说明如何在调用“ handle_read”时链接不同的处理程序和数据处理在同一读取处理程序中,总是像“在屏幕上打印一些数据”之类的东西。 Which, I think, is completely wrong when compared to real world problems! 与现实世界中的问题相比,我认为这是完全错误的! No one will just print data and finish the execution of her program...! 没有人会只打印数据并完成程序的执行...! Usually once the data is received there is another treatment that has to start, for example FireAnEvent(). 通常,一旦接收到数据,就必须开始另一种处理,例如FireAnEvent()。 Influenced by the bad examples, I have done this 'FireAnEvent' inside the read handler, which, obviously is completely wrong! 受不良示例影响,我在读取处理程序中执行了此“ FireAnEvent”,这显然是完全错误的! It is bad to do that because making the things like that, the "handle_read" might never exit or exit too late. 这样做是不好的,因为做这样的事情,“ handle_read”可能永远不会退出或退出得太晚。 If this handler does not finish, the io_service loop will not finish too. 如果此处理程序未完成,则io_service循环也不会完成。 And if your further treatment demands once again to your async client to do something, this will start/restart (I am not sure about the details) the io_service loop. 而且,如果您的进一步处理要求异步客户端再次执行某项操作,则它将启动/重新启动io_service循环(我不确定细节)。 In my case I was doing several calls to the async client in this way. 就我而言,我以这种方式对异步客户端进行了多次调用。 At the end I saw how the io_service was always started but never ended. 最后,我看到了io_service如何始终启动但从未结束。 Even after the whole treatment was ended, I never saw the io_service to stop. 即使整个治疗结束后,我也从未见过io_service停止。 So finally I let my async client to fill some global variable with the received data inside the handle_read and not to call directly another function like FireAnEvent. 所以最后,我让异步客户端在handle_read中用接收到的数据填充一些全局变量,而不是直接调用另一个函数,例如FireAnEvent。 And I moved the call of this function (FireAnEvent) just after the io_service.run(). 我在io_service.run()之后移动了对该函数(FireAnEvent)的调用。 And it worked because after the end of the run() method I know that the loop is completely finished! 之所以起作用,是因为在run()方法结束后,我知道循环已完全结束! I hope my answer will help people :) 希望我的回答对人们有所帮助:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM