Failed to retrieve data with Qt from deployed Node.js server using WebSockets

I wrote a simple server example in JavaScript that sends some data to a client when the client connects: send-gravity-from-server-to-client-box2d-wasm-js

I deployed this simple server on free hostings: https://glitch.com/ and https://render.com/

Web clients work well:

(It takes 15-20 seconds for Glitch and 50 seconds for Render to wake up the server)

I try to connect to the server from Qt and show received data:

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    connect(&m_webSocket, &QWebSocket::connected, this, &Widget::onConnected);
    connect(&m_webSocket, &QWebSocket::textMessageReceived,
            this, &Widget::onMessageReceived);
    connect(&m_webSocket, &QWebSocket::errorOccurred,
            this, &Widget::errorOccurred);

    // QUrl url("wss://send-gravity-box2d-wasm-js.onrender.com");
    QUrl url("wss://merciful-regal-soursop.glitch.me");
    m_webSocket.open(url);
}

Widget::~Widget() {}

void Widget::onConnected()
{
    qDebug() << "connected";
}

void Widget::onMessageReceived(const QString &message)
{
    qDebug() << message;
}

void Widget::errorOccurred(QAbstractSocket::SocketError error)
{
    qDebug() << error;
}

I see:

connected
QAbstractSocket::RemoteHostClosedError
QAbstractSocket::RemoteHostClosedError

in the Qt Debug console when I try to connect to Render and I see QAbstractSocket::ConnectionRefusedError when I try to connect to Glitch.

do you know if this sends a User-Agent header? Glitch requires one to be present. my searching shows that QWebSocket has an open method that takes a network request QWebSocket Class | Qt WebSockets 6.7.1. try using that

2 Likes

QNetworkRequest has the setRawHeader() method. What should I send in the second parameter? Where to find the User-Agent value for my application on Glitch?

    QUrl url("wss://merciful-regal-soursop.glitch.me");

    QNetworkRequest request;
    request.setUrl(url);
    request.setRawHeader(QByteArray("User-Agent"), QByteArray(""));

    m_webSocket.open(request);

@wh0 Thank you very much! I are right. It is a problem with User-Agent. I found a way to find out it:

console.log(window.navigator.userAgent);

Copy and paste the resulting string value above into the second argument of the setRawHeader() method:

    QUrl url("wss://merciful-regal-soursop.glitch.me");

    QNetworkRequest request;
    request.setUrl(url);
    request.setRawHeader(QByteArray("User-Agent"), QByteArray("Mozilla/5.0 "
        "(Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
        "Chrome/124.0.0.0 Safari/537.36"));

    m_webSocket.open(request);
1 Like

cool, glad that worked. you don’t have to match the browser. Glitch seems to be friendly to non-browser clients too. feel free to set a user-agent that identifies your desktop app

1 Like

My following Qt 6.6.3 example works on Android, Desktop, and Web (with Qt WebAssembly). It prints data received from the server. The server contains the Box2D-WASM library. It sends the gravity value in JSON format when a client is connected. It is useful example to make multiplayer games with physics on the server side. I have deployed the example on free Glitch hosting: Glitch :・゚✧ from the GitHub repository: send-gravity-from-server-to-client-box2d-wasm-js The client contains only one main.cpp file. It outputs the following information to the console:

connected
"{\"action\":\"scGravity\",\"data\":\"{\\\"x\\\":0,\\\"y\\\":-3}\"}"

You should download OpenSSL to run the following example on Android. Open the following window in Qt Creator (Edit > Preferences... > Devices > Android):

Add the following path to your pro-file:

QT += core gui websockets widgets

android: include(C:/Qt/Tools/OpenSSL-1.1.1j/Win_x64/bin/openssl.pri)

CONFIG += c++17

SOURCES += \
    main.cpp

Read how to add OpenSSL to your CMake project if you use CMake instead of QMake in the Qt documentaion: Adding OpenSSL Support for Android

Build the following example for Android, Desktop, and WebAssembly (I have tested it):

main.cpp

#include <QtNetwork/QNetworkRequest>
#include <QtWebSockets/QWebSocket>
#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>

class Widget : public QWidget
{
    Q_OBJECT

public:

    Widget()
    {
        setWindowTitle("Show gravity from server with Box2D-WASM");
        resize(420, 200);

        connect(&m_webSocket, &QWebSocket::connected,
            this, &Widget::onConnected);
        connect(&m_webSocket, &QWebSocket::textMessageReceived,
            this, &Widget::onMessageReceived);
        connect(&m_webSocket, &QWebSocket::errorOccurred,
            this, &Widget::onErrorOccurred);

        QUrl url("wss://merciful-regal-soursop.glitch.me");

        QNetworkRequest request;
        request.setUrl(url);
        request.setRawHeader(QByteArray("User-Agent"), QByteArray("Mozilla/5.0 "
            "(Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
            "Chrome/124.0.0.0 Safari/537.36"));

        m_webSocket.open(request);
    }
    ~Widget() {}

private slots:

    void onConnected()
    {
        qDebug() << "connected";
    }
    void onMessageReceived(const QString &message)
    {
        qDebug() << message;
    }

    void onErrorOccurred(QAbstractSocket::SocketError error)
    {
        qDebug() << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";
        qDebug() << "Error:" << error;
        qDebug() << "Device supports OpenSSL:" << QSslSocket::supportsSsl();
        qDebug() << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";
    }

private:

    QWebSocket m_webSocket;
};

#include "main.moc"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    Widget w;
    w.show();
    return app.exec();
}