websocket 如何支持协程
Hi, WS clients and controllers does not support coroutines natively now. However, you can wrap a AsyncTask within them.
wsPtr->setMessageHandler([](const std::string &message,
const WebSocketClientPtr client&,
const WebSocketMessageType &type) {
[message, client, type]() -> AsyncTask {
co_await you_function(...);
}();
}
Same works for servers
@marty1885 It seems that variables cannot be captured using =, Because it will be destructed, Do you know why?
int main() {
{
auto ptr = std::make_shared<std::string>("hh");
drogon::async_run([ptr]() -> drogon::AsyncTask {
std::cout << "start co_await test2()" << std::endl;
try {
std::cout << ptr.use_count() << std::endl;
co_await test2();
std::cout << ptr.use_count() << std::endl;
} catch (...) {
std::cout << "异常" << std::endl;
}
std::cout << "end co_await test2()" << std::endl;
co_return;
});
}
}
➜ git:(master) ✗ ./a.out
start co_await test2()
2
test2 start sleep
test2 end sleep
0
end co_await test2()
@nqf May you share the full source code and the compiler you use? I can't tell without knowing that test2 is.
My guess is that you want to use sync_wait instead of async_run. async_runc returns immediately when it needs to wait, which in your case reaches the end of the program. Thus the true execution order is:
- main()
- async_run()
- Your lambda coroutine
std::cout << "start co_await test2()" << std::endl;std::cout << ptr.use_count() << std::endl;test2()test2suspends the coroutine- Continue executing after async_run
- Reached program end. Destructing everything
test2got resumed while destructingstd::cout << ptr.use_count() << std::endlstd::cout << "end co_await test2()" << std::endl;- Exit
Or put app().run() at the end of main to keep the event loop running.
Important: sync_wait accepts a Task<T> instead of a coroutine function. The syntax is rogon::async_run([ptr]() -> drogon::Task<> {...} ());
The naming is weird. And in most cases you want to use Task insead of AsyncTask. Task<> is fully async. And AsyncTask should be named FireAndForget, it's named that way because of internal C++ details.