zaphoyd / websocketpp

C++ websocket client/server library
http://www.zaphoyd.com/websocketpp
Other
6.97k stars 1.97k forks source link

Add some asynchronous examples? #1086

Open lkpworkspace opened 1 year ago

lkpworkspace commented 1 year ago

like this void on_http(connection_hdl hdl), I can only process one request at the same time

sierret commented 1 year ago

When you say only one request, do you mean you want to run multiple websocket connections? Or do you mean you want a way to empty the message buffer(what holds incoming messages before they are read) in a parallel way?

Either way, I think you'll end up using the telemetry_client example. Basically, at the bottom of the typical websocketpp object "void start" function instead if:

m_endpoint.run(); //start websocket object event loop

You have:

websocketpp::lib::thread asio_thread(&client::run, &m_client); //create asynchronous event loop thread

asio_thread.detach(); //run asynchronous event loop thread

Be sure to have something like a infinite while loop or something running in the main thread. Otherwise, you'll get a segmentation fault. You can either have a separate main thread or choose a websocket connection to be the main. If it's the latter, on the main thread websocketpp client object, you will use:


websocketpp::lib::thread asio_thread(&client::run, &m_client); //create asynchronous event loop thread

asio_thread.join(); //use .join() instead of .detach()

And this "main thread" websocket object connection needs to be instantiated LAST. Or else it will block any later code from running.

Also maybe read up on on threading, mainly what join and detach actually does.

lkpworkspace commented 1 year ago

I think I have found a way to process http asynchronously in websocket server

/// in websocket server main loop
void on_http(connection_hdl hdl) {
  // TODO save hdl
  // ...

  // Call `defer_http_response` to delay processing without blocking the loop
  server::connection_ptr con = m_endpoint.get_con_from_hdl(hdl);
  con->defer_http_response();
}

/// in other thread
// TODO Get one connection to be processed
// ...

con->set_code(...);
con->set_body(...);
con->send_http_response();

I don't know if this is right

sierret commented 1 year ago

I'm not an huge expert but I don't know why you need to defer the response. All that does is stop the connection from timing out. To me it just sounds like extra overhead with no benefit for you. Specifically, I highly doubt it helps your situation as the documents specifically say that it will (likely) tie up resources. defer_http_response() will only slow down your program and won't help running asynchronously.

If you actually want asynchronous requests(and responses) why don't you use in your object .start function:

websocketpp::lib::thread asio_thread(object_run_function, your_object);
asio_thread.detach(); //or asio_thread.join(); if you want it running in the main thread

instead of:

m_endpoint.run();

that I mentioned earlier. It would run with each object function/handler running asynchronously upon a new response/message (as I understand it) .