logo头像

技术引领生活!

Qt下的Websocket

本文于1694天之前发表,文中内容可能已经过时。

在上一篇中介绍了使用 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;

如下图所示
ws测试echo

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);
}

//返回建立的socket
return socket;
}

测试工程下载

测试工程

支付宝打赏 微信打赏

您的支持是我前行的动力!