如何让基于cpprestsdk(casablanca)的REST API服务器持续运行
解决cpprestsdk服务器无法持续运行的问题
嘿,这个问题我太熟了!cpprestsdk的openServer()(底层其实是http_listener::open())是非阻塞调用——意思是它启动服务器后会立刻返回,你的main函数执行完后续代码就直接退出了,服务器自然跟着停掉。完全不用写空循环浪费CPU,有更优雅的解决办法:
最优方案:用cpprestsdk自带的wait()方法
cpprestsdk的http_listener类本身就提供了wait()方法,它会阻塞当前线程,直到服务器被主动关闭(比如调用close())。你只需要在自己的TransactionController里封装这个方法就行:
第一步:给TransactionController添加wait方法
假设你的TransactionController里有个http_listener成员变量,补充代码如下:
class TransactionController { private: web::http::experimental::listener::http_listener m_listener; // 你的其他成员变量... public: // 你已有的方法:setEndpoint、initHandlers、openServer... // 新增wait方法,封装listener的阻塞逻辑 void wait() { m_listener.wait(); } // 可选但推荐:添加关闭服务器的方法 void closeServer() { m_listener.close().wait(); } };
第二步:修改main函数调用wait()
int main() { cout << "Starting Server" << endl; TransactionController server; server.setEndpoint("http://0.0.0.0:4200/api"); server.initHandlers(); try { server.openServer(); cout << "Server listening at: " << server.getEndpoint() << endl; // 阻塞主线程,直到服务器被主动关闭 server.wait(); } catch (const std::exception& e) { cout << "Error: " << e.what() << endl; return 1; } return 0; }
快速测试方案:用输入阻塞
如果你只是想快速验证功能,不想修改TransactionController,可以用输入操作来阻塞主线程:
int main() { cout << "Starting Server" << endl; TransactionController server; server.setEndpoint("http://0.0.0.0:4200/api"); server.initHandlers(); try { server.openServer(); cout << "Server listening at: " << server.getEndpoint() << endl; cout << "Press Enter to stop the server..." << endl; // 阻塞直到用户按下回车键 std::cin.get(); // 记得主动关闭服务器(好习惯) // server.closeServer(); } catch (const std::exception& e) { cout << "Error: " << e.what() << endl; return 1; } return 0; }
为什么别用while(true)?
空循环while(true)会让CPU一直处于满负荷空转状态,完全是浪费资源。而wait()方法会让线程进入休眠,只有当服务器收到请求或者关闭信号时才会唤醒,效率高得多。
内容的提问来源于stack exchange,提问作者Biggytiny
相关产品推荐
相关产品推荐

