1

i've created an async beast server that gets a request from a browser, opens a second socket , writes the request , gets the response and sends it back to the browser. all async . as the "send back to browser" action waits to the read handler completion to trigger

void
on_write(
    boost::system::error_code ec,
    std::size_t bytes_transferred)
{
    boost::ignore_unused(bytes_transferred);

    if(ec)
        return fail2(ec, "write");
    std::cout << "===========on_write============" << std::endl;
    stopper("async_write" , 0);
    stopper("on_write" , 1);
    // Receive the HTTP response
    http::async_read(redirect_stream_, redirect_buffer_, redirect_res_,
        std::bind(
            &session2::on_read,
            shared_from_this(),
            std::placeholders::_1,
            std::placeholders::_2));
}

void
on_read(
    boost::system::error_code ec,
    std::size_t bytes_transferred)
{
    boost::ignore_unused(bytes_transferred);

    if(ec)
        return fail2(ec, "read");
    std::cout << "===========on_read============" << std::endl;
    stopper("on_write" , 0);
    stopper("on_read" , 1);
    // Write the message to standard out
    std::cout << redirect_res_.base() << std::endl;
    http::async_write(stream_, redirect_res_,
                      std::bind(
                          &session2::start_shutdown,
                          shared_from_this(),
                          std::placeholders::_1,
                          std::placeholders::_2));
    // Gracefully close the stream

}

it seems (from checks i have done) that it takes to long before the "write to browser" action is triggered (the on_read function) is there a better way to reduce the response to browser time? maybe by "read_some" method?

redemption
  • 13
  • 4

1 Answers1

0

Depends a lot on the goal. If you really wish to transparently relay request/response without any modification, then read_some will be a better approach (but you won't need anything from Beast, just Asio).

Using Beast, you can read partial requests as well, assuming you might want to modify some things about the messages being relayed, you might e.g. use message_parser<...> instead of message<> and use http::read_header and a loop to read a buffer_body.

There's an example in the docs that implements things like this: HTTP Relay example.

You can also search my answers: https://stackoverflow.com/search?q=user%3A85371+beast+read_header or for buffer_body and or request_parser/response_parser

Beyond that there are many small ways to reduce latency (proper planning of threads, executors, allocators). But for something like that you should probably post your code (to CodeReview?).

sehe
  • 374,641
  • 47
  • 450
  • 633
  • thanks sehe. maybe i'm missing something . shouldn't the async operation reduce latency (gets lower latency then the sync)? because your examples are all sync. – redemption Sep 09 '21 at 13:53
  • My examples were supposed to highlight the parser/serializer interface (as opposed to the ready-made composed read/write operations). You can use the `async_` variation of all of them. The point is that then you control when you start relaying the response to the other side, instead of waiting for the whole thing to be received (and parsed) – sehe Sep 09 '21 at 15:21
  • so if i understand it correct , first i have to get the response full headers , that should trigger the write (the headers) to the browser and meanwhile the rest of the response will be received . so what will trigger the rest of the write? – redemption Sep 09 '21 at 15:48
  • 1
    i'll search for examples to the ops you suggested i appreciate your patient and quick answer!!! – redemption Sep 09 '21 at 15:56
  • Basically. Yes, if you don't wait for the full message to arrive you can start relaying immediately. "What will trigger the rest" - the arrival of "rest" :) You can relay block by block – sehe Sep 09 '21 at 18:46