如何优雅地停止 uWebSockets 服务器?
Posted
技术标签:
【中文标题】如何优雅地停止 uWebSockets 服务器?【英文标题】:How can I gracefully stop a uWebSockets server? 【发布时间】:2018-11-13 16:51:01 【问题描述】:如何退出官方示例中的run()
调用?比如收到信号后。
uWS::SSLApp(
/* There are tons of SSL options */
.cert_file_name = "cert.pem",
.key_file_name = "key.pem"
).onGet("/", [](auto *res, auto *req)
/* Respond with the web app on default route */
res->writeStatus("200 OK")
->writeHeader("Content-Type", "text/html; charset=utf-8")
->end(indexHtmlBuffer);
).onWebSocket<UserData>("/ws/chat", [&](auto *ws, auto *req)
/* Subscribe to topic /chat */
ws->subscribe("chat");
).onMessage([&](auto *ws, auto message, auto opCode)
/* Parse incoming message according to some protocol & publish it */
if (seemsReasonable(message))
ws->publish("chat", message);
else
ws->close();
).onClose([&](auto *ws, int code, auto message)
/* Remove websocket from this topic */
ws->unsubscribe("chat");
).listen("localhost", 3000, 0).run();
【问题讨论】:
@Vadim 有解决方案吗? @Vahagn 不,我刚刚编辑了问题 【参考方案1】:在a documentation中,写着如下:
许多用户询问他们应该如何停止事件循环。事情不是这样的,你从不阻止它,你让它失败。通过关闭所有套接字、停止监听套接字、删除任何计时器等,循环将自动导致 App.run 正常返回,而不会出现内存泄漏。
由于应用程序本身受 RAII 控制,一旦阻塞的 .run 调用返回并且应用程序超出范围,所有内存将被优雅地删除。
所以这意味着你必须释放函数内部的每个源。所以例如这个:
void testThread()
std::this_thread::sleep_for(15s);
us_listen_socket_close(0, listen_socket);
int main()
std::thread thread(testThread);
uWS::App app;
/* Very simple WebSocket broadcasting echo server */
app.ws<PerSocketData>("/*",
/* Settings */
.compression = uWS::SHARED_COMPRESSOR,
.maxPayloadLength = 16 * 1024 * 1024,
.idleTimeout = 10,
.maxBackpressure = 1 * 1024 * 1204,
/* Handlers */
.open = [](auto* ws, auto* req)
/* Let's make every connection subscribe to the "broadcast" topic */
ws->subscribe("broadcast");
,
.message = [](auto* ws, std::string_view message, uWS::OpCode opCode)
,
.drain = [](auto* ws)
/* Check getBufferedAmount here */
,
.ping = [](auto* ws)
,
.pong = [](auto* ws)
,
.close = [](auto* ws, int code, std::string_view message)
std::cout << "Client disconnect!" << std::endl;
/* We automatically unsubscribe from any topic here */
).listen(9001, [](auto* token)
listen_socket = token;
if (token)
std::cout << "Listening on port " << 9001 << std::endl;
);
app.run();
std::cout << "Shutdown!" << std::endl;
并且在调用 testThread 之后,服务器应该退出(如果没有连接客户端,否则,您还应该断开连接的客户端(套接字))并在 run() 行之后继续。断开客户端后,我的输出如下:
监听 9001 端口
客户端断开连接!
客户端断开连接!
客户端断开连接!
客户端断开连接!
客户端断开连接!
客户端断开连接!
关机!
【讨论】:
你试过这个代码吗?当我试图通过单元测试反复设置服务器时,我所有的尝试都会导致服务器挂起。 目前没有,但现在可以,它可以工作,但它与上面的代码不同,因为我的版本有点不同。 我已经编辑了这个例子。这是我测试过的并且有效。我成功退出线程,控制台中有“关机”。以上是关于如何优雅地停止 uWebSockets 服务器?的主要内容,如果未能解决你的问题,请参考以下文章