[2020-04-23 16:29:46] [library] asio::listen called from the wrong state
terminate called after throwing an instance of ‘websocketpp::exception’
what(): invalid state
Aborted
最近在一个AI项目C++开发中,测试时遇到了一个恼人的问题,
软件使用了websocketpp 作为通信方式,但是每次测试时,程序退出了,指定的websocket 端口8765 还是被占用着,需要过几分钟才会被系统释放。
如果能在程序退出时,自动立刻关闭端口呢?
经过一番实践,把核心相关代码分享给需要的朋友参考。
这个任务分解为以下3步:
程序退出时需要设置一个拦截器,在程序退出时自动调用
在main() 函数中,注册
const int autoCloseWebSocket = std::atexit(UsbInput::VirtualUsbServer::shutdownWebsocket);
if (autoCloseWebSocket!= 0) {
std::cerr << “注册WebSocket在程序退出时自动关闭失败.\n”;
return EXIT_FAILURE;
}
websocketpp 如何关闭指定端口
void VirtualUsbServer::shutdownWebsocket(){
websocket_server.stop_listening();
LOG(INFO)<< " Websocket端口已经关闭. " << std::endl;
}
测试样本代码,确保可以正常工作。 具体代码如下:
#include
#include
#include
#include "UsbEmulator.h"
#include "MouseDeviceParser.h"
#include "KeyboardDeviceParser.h"
#include "VirtualUsbServer.h"
#include "HappyTool.h"
#include
#include
#include
#include
void VirtualUsbServer::shutdownWebsocket(){
websocket_server.stop_listening();
LOG(INFO)<< " Websocket端口已经关闭. " << std::endl;
}
int main(int argc, char* argv[]) {
/**
日志级别
glog 支持四种日志级别,INFO、WARNING、ERROR和FATAL。默认情况下,在打印完FATAL日志之后,程序将会终止。ERROR和FATAL的日志除了会写到日志中,还会输出到 stderr。
*/
// 解析命令行参数
gflags::ParseCommandLineFlags(&argc, &argv, true);
// 初始化日志库
google::InitGoogleLogging(argv[0]);
google::SetLogDestination(google::INFO, "log/"); // 把日志同时记录文件,最低级别为INFO
UsbInput::VirtualUsbServer serverInstance=UsbInput::VirtualUsbServer();
const int autoCloseWebSocket = std::atexit(UsbInput::VirtualUsbServer::shutdownWebsocket);
if (autoCloseWebSocket!= 0) {
std::cerr << "注册WebSocket在程序退出时自动关闭失败.\n";
return EXIT_FAILURE;
}
serverInstance.start_server();
return 0;
}