在上一篇中介绍了使用 Qt 开发 HttpServer 常用的库,但是由于 HTTP 的特性使得只能是客户端主动请求,在对实时性要求比较高的情况下就需要轮询操作,WebSocket 的出现彻底改变这一现象
WebSocket 的使用 1 2 3 4 5 graph LR A[HTTP 轮询]-->D(WS中断) style A fill:#2ff,fill-opacity:0.6,stroke:#faa,stroke-width:4px style D stroke:#000,stroke-width:4px;
如下图所示
Qt 对 webSocket 支持的比较好,甚至还带了一个例子,乍一看还比较复杂,本人修改了下,简单易用,和 QTcpServer 非常想像
在工程中引入 websockets
引入 QWebSocketServer
编写 JS 代码
CPP 核心代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 QWebSocketServer *server = new QWebSocketServer("Spygg Server", QWebSocketServer::NonSecureMode, this); if (!server ->listen (QHostAddress::Any , 12345 )){ qFatal("开服WS服务器失败"); } connect (server , &QWebSocketServer::newConnection, this, [&, server ](){ QWebSocket *socket = server ->nextPendingConnection(); connect (socket, &QWebSocket::textMessageReceived, this, [=](QString message){ socket->sendTextMessage(message); }); connect (socket, &QWebSocket::disconnected, this, [&](){ //这里非常重要,在文档中说明了nextPendingConnection产生的socket要自己手动回收 QWebSocket *sc = qobject_cast<QWebSocket *>(sender()); if (sc){ sc->close (); sc->deleteLater(); sc = Q_NULLPTR; } }); });
html 代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 function wsCommution ( ) { if (location.search != "" ) var baseUrl = (/[?&]webChannelBaseUrl=([A-Za-z0-9\-:/\.]+)/ .exec(location.search)[1 ]); else var baseUrl = "ws://localhost:12345" ; output("Connecting to WebSocket server at " + baseUrl + "." ); var socket = new WebSocket(baseUrl); socket.onclose = function ( ) { console .error("web channel closed" ); }; socket.onerror = function (error ) { console .error("web channel error: " + error); }; socket.onopen = function ( ) { output("WebSocket connected, setting up QWebChannel." ); document .getElementById("send" ).onclick = function ( ) { socket.send(text); } output("Connected to WebChannel, ready to send/receive messages!" ); }; socket.onmessage = function (msg ) { output("Received message:" + msg.data); } return socket; }
测试工程下载 测试工程