uWebSockets C++发送报错:cork buffer未检查cancork致崩溃
嵌入式WebSocket服务器崩溃问题排查
问题背景
我正在为嵌入式系统开发WebSocket服务器,核心需求是向WebApp订阅的信号ID列表推送更新。原本运行正常,但近期频繁出现崩溃,怀疑和corking机制有关,且在多种场景下都能复现。我自行实现了发布/订阅机制,通过独立线程以每秒10次的频率异步向客户端发送包含多信号更新的批量消息。崩溃似乎发生在发送操作与message回调冲突的场景下。
应用配置代码
auto app = uWS::App() .ws<ClientData>( "/*", { /* Settings */ .compression = uWS::CompressOptions(uWS::DEDICATED_COMPRESSOR_4KB | uWS::DEDICATED_DECOMPRESSOR), .maxPayloadLength = 100 * 1024 * 1024, .idleTimeout = 16, .maxBackpressure = 100 * 1024 * 1024, .closeOnBackpressureLimit = false, .resetIdleTimeoutOnSend = false, .sendPingsAutomatically = true, /* Handlers */ // handshaking callback .upgrade = [this](auto *res, auto *req, auto *context) { auto subprotocols = String(req->getHeader("sec-websocket-protocol")); auto jwt = this->GetJwtFromSubprotocols(subprotocols); if(!this->ValidateJwt(jwt)) { res->writeStatus("401"); res->end("Invalid jwt"); return; } if(this->IsMaximumCapacityReached()) { res->writeStatus("503"); res->end("Maximum number of clients reached"); return; } res->upgrade(ClientData{}, req->getHeader("sec-websocket-key"), req->getHeader("sec-websocket-protocol"), req->getHeader("sec-websocket-extensions"), context); }, .open = [this](auto *ws) { this->OnOpen(ws); }, .message = [this](auto *ws, std::string_view message, uWS::OpCode) { this->OnMessage(ws, message); }, .dropped = [](auto * /*ws*/, std::string_view /*message*/, uWS::OpCode /*opCode*/) { /* A message was dropped due to set maxBackpressure and closeOnBackpressureLimit limit */ }, .drain = [](auto * /*ws*/) { /* Check ws->getBufferedAmount() here */ }, .ping = [](auto * /*ws*/, std::string_view) { /* Not implemented yet */ }, .pong = [](auto * /*ws*/, std::string_view) { /* Not implemented yet */ }, .close = [this](auto *ws, int /*code*/, std::string_view /*message*/) { this->OnClose(ws); } }) .listen("127.0.0.1", 50000, [](auto *listen_socket) { if(listen_socket) { LogDebug("Ready on port 50000"); } });
发送线程逻辑
发送线程通过互斥锁保护,循环执行以下代码:
Sync lock(*_clientsMutex); for(auto client : *_clients) { SendRealtimeUpdate(client); }
其中SendRealtimeUpdate方法处理后生成std::string类型的消息,通过client->send(msg, uWS::OpCode::TEXT);发送。
已尝试方案与疑问
试过uWebSockets内置的发布/订阅机制(以信号ID为主题),该机制运行稳定,但只能单信号发送,效率太低,不符合批量推送的需求。我猜测问题根源是message回调和线程发送操作之间缺少同步机制。
内容的提问来源于stack exchange,提问作者Simone
相关产品推荐
相关产品推荐

