Qt和Node JS通过WebSockets进行网络通信

Qt and Node JS network communication through WebSockets

本文关键字:网络通信 WebSockets 通过 Node JS Qt      更新时间:2023-10-16

我想将我的节点JS应用程序与Qt(C++(程序连接,我正在使用 Socket.io 用于节点JS(服务器(,QWebSocket用于Qt程序(客户端(。

但是在我所有的试验之后,我还没有开始工作。 它向我显示了客户端的错误:

QAbstractSocket::RemoteHostClosedError

从服务器端看,没有传入连接的迹象。

这是我用于此目的的源代码:

节点JS服务器:

var io = require('socket.io')(8082);
io.on('connection', function (socket) {
  io.emit('this', 'Hey Welcome!');
   console.log("New connection!");
  socket.on('private message', function (from, msg) {
    console.log('I received a private message by ', from, ' saying ', msg);
  });
  socket.on('disconnect', function () {
    io.emit('user disconnected');
  });
});

Qt C++客户端:

    #include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) : QWidget(parent),  ui(new Ui::Widget)
{
    ui->setupUi(this);
    webSocket  = new QWebSocket();
    webSocket->open(QUrl(("ws://localhost:8082")));
    connect(webSocket, SIGNAL(connected()), this, SLOT(isConnected()));
    connect(webSocket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(sslError(QList<QSslError>)));
    connect(webSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(logError(QAbstractSocket::SocketError)));
    connect(webSocket, SIGNAL(textMessageReceived(QString)), this, SLOT(newMessage(QString)));
    connect(webSocket, SIGNAL(textFrameReceived(QString,bool)), this, SLOT(newMessageBit(QString,bool)));
}
Widget::~Widget()
{
    delete ui;
}

void Widget::isConnected()
{
    webSocket->sendTextMessage("Hello From Qt!!!");
}
void Widget::logError(QAbstractSocket::SocketError err)
{
    qDebug() << "Error: ";
    qDebug() << err;
}
void Widget::sslError(QList<QSslError> errors)
{
    qDebug() << "SSLError: ";
    qDebug() << errors;
    webSocket->ignoreSslErrors(errors);
}

void Widget::newMessage(QString msg)
{
    qDebug() << msg;
}
void Widget::newMessageBit(QString msg, bool isLast)
{
    qDebug() << msg;
    qDebug() << isLast;
}

我也从调试控制台收到这些错误(在运行时(

QSslSocket: cannot resolve TLSv1_1_client_method
QSslSocket: cannot resolve TLSv1_2_client_method
QSslSocket: cannot resolve TLSv1_1_server_method
QSslSocket: cannot resolve TLSv1_2_server_method
QSslSocket: cannot resolve SSL_select_next_proto
QSslSocket: cannot resolve SSL_CTX_set_next_proto_select_cb
QSslSocket: cannot resolve SSL_get0_next_proto_negotiated

虽然我迟到了,但如果有人也面临这个问题(不包括 ssl 错误(,它可能会很有用。首先,socket.io 与Qt(或C ++,java,php或任何其他语言(使用的标准websocket不兼容。如果您在服务器上使用 socket.io,那么您只能使用 socket.io 特定的客户端库,而不能使用标准的 websocket 库。

其他语言中有几个 socket.io 特定的客户端库 -

Java: https://github.com/socketio/socket.io-client-java
C++: https://github.com/socketio/socket.io-client-cpp
Swift: https://github.com/socketio/socket.io-client-swift
Dart: https://github.com/rikulo/socket.io-client-dart
Python: https://github.com/miguelgrinberg/python-socketio
.Net: https://github.com/Quobject/SocketIoClientDotNet

很可能系统上的OpenSSL动态库与Qt构建的动态库不兼容。您使用的是哪个Qt版本?由于您没有指定操作系统,因此很难判断这是否是因为系统本身提供了OpenSSL的旧版本,但我建议使用任何可用的转储工具在OpenSSL库中查找符号(例如SSL_get0_next_proto_negotiated(,如果它们不存在 - 降级Qt或升级OpenSSL。

如此处所述 - 从Qt 5.2及更高版本开始,您至少需要OpenSSL 1.0.0,旧版本可能会失败。

更新

正如我怀疑您在SSL上遇到的错误实际上是由于糟糕的OpenSSL二进制文件造成的。您可以从 Shining Light Productions 站点获取适用于 Windows 的 1.0.0+ 库,但这只能修复 OpenSSL 错误。我以您的为例并添加了额外的插槽,似乎stateChanged信号是用状态QAbstractSocket::ConnectingState触发的,但之后什么也没发生。