【问题标题】:Qt and Node JS network communication through WebSocketsQt 和 Node JS 通过 WebSockets 进行网络通信
【发布时间】:2016-05-28 01:32:16
【问题描述】:

我想将我的 Node 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

【问题讨论】:

    标签: c++ node.js qt websocket network-programming


    【解决方案1】:

    虽然我迟到了,但如果有人也面临这个问题(不包括 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
    

    【讨论】:

      【解决方案2】:

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

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

      更新

      我怀疑您遇到的 SSL 错误确实是由于 OpenSSL 二进制文件错误造成的。您可以从Shining Light Productions 站点获取适用于 Windows 的 1.0.0+ 库,但这只能修复 OpenSSL 错误。我举了你的例子并添加了额外的插槽,似乎stateChanged 信号以QAbstractSocket::ConnectingState 状态触发,但之后没有任何反应。

      【讨论】:

      • 谢谢你的回答,但我不知道什么是 OpenSSL,我只是听说过,我只知道它是为了安全,但我没有在我的代码中指定我想要安全,我不知道为什么 Qt 试图使用它。我正在使用 Qt 5.4 运行 Windows7。我从来没有在我的系统上安装过 OpenSSL;我想我只需要安装它。但如果是这样,所有其他用户也需要安装它才能使用我的程序;不能只禁用 SSL 吗?
      • @Xsmael 我对 websockets 不太熟悉,但您似乎使用的是 ws 网址而不是 wss,所以是的,套接字不应该使用 SSL 安全性。虽然不确定socket.io - 也许它默认启用SSL,我需要谷歌一下。
      • @Xsmael - 你有没有机会使用 Wireshark 查看发生了什么?
      • @Xsmael - 据我在 Wireshark 中看到的,最初的 GET 请求没有发送 - 不知道为什么。
      • 非常感谢您付出的所有努力和时间,我也尝试了wireshark,但没有太大帮助,但显然,Qt 和 Socket.io (node js) 之间存在关于 websocket 的不兼容协议实现。所以我尝试了其他库,我得到了一个可以工作的库(ws)。关于 OpenSSL 警告,您确实是对的,但显然正如您所发现的,它们不对通信失败负责。请参阅stackoverflow.com/questions/26361145/…,因为我们不使用 ssl,但安装正确的库会清除这些警告。谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-20
      • 2012-07-26
      • 1970-01-01
      • 2012-01-12
      • 2018-10-22
      • 1970-01-01
      相关资源
      最近更新 更多