Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Game Development
  4. Qt SFML. Example of connection with local and remote JavaScript server with WebSockets
Forum Update on Monday, May 27th 2025

Qt SFML. Example of connection with local and remote JavaScript server with WebSockets

Scheduled Pinned Locked Moved Game Development
1 Posts 1 Posters 576 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • 8 Offline
    8 Offline
    8Observer8
    wrote on 7 Nov 2021, 09:30 last edited by 8Observer8 11 Jul 2021, 14:44
    #1

    Qt Version: 5.15.2
    SFML: 2.5.1

    Qt SFML Client: https://github.com/8Observer8/NodeJSWebSocketClient_QtSFML_Qt5Cpp
    Node.js server: https://github.com/8Observer8/nodejs-websocket-server-js

    Hello,

    It is not a question. It is just a simple example. It will be useful for someone who wants to write a multiplayer games with QtWebSockets and SFML. I found somewhere an example for integration of SFML to Qt Widget. There is a class called "QSfmlWidget". You can copy "QSfmlWidget.h" and "QSfmlWidget.cpp" to your project and inherit from QSfmlWidget your widget. Override to methods in your widget: onInit() and onUpdate(). My example contains a simple server script that you can upload on free Heroku server. The Qt client draws a rectangle using SFML:

    7b911ab3-b012-4020-a151-7032eaf2509e-image.png

    and makes a connection with Node.js server. The Qt client send the message "Hello, server!". The server send the message "Hello, client!". The server and the client print these messages to the console. The Qt client will print to the console the message:

    Connection
    "{\"msg\":\"Hello, client!\"}"
    "Hello, client!"
    

    If you need a local server just comment/uncomment the respective line of code:

    //    QUrl url("ws://localhost:3000");
        QUrl url("ws://nodejs-websocket-server-js.herokuapp.com");
        m_webSocket.open(url);
    

    Server:

    app.js

    const express = require("express");
    const http = require("http");
    const ws = require("ws");
    const path = require("path");
    const fs = require("fs");
    
    const app = express();
    app.use(express.static(path.join(__dirname, "./public")));
    app.get("/", (req, res) => { res.sendFile(path.join(__dirname, "index.html")) });
    
    const httpServer = http.createServer(app);
    const wss = new ws.Server({ server: httpServer });
    
    wss.on("connection",
        (ws) =>
        {
            console.log("Client was connected");
    
            ws.send(JSON.stringify({ msg: "Hello, client!" }));
    
            ws.onmessage =
                (event) =>
                {
                    const msg = JSON.parse(event.data);
                    console.log(msg);
                };
        });
    
    const port = process.env.PORT || 3000;
    httpServer.listen(port, () => { console.log("Server started. Port: ", port); });
    

    It is a web client, just for example:

    index.html

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    
        <title>Web Client</title>
    </head>
    
    <body>
        <script>
            const ws = new WebSocket("ws://localhost:3000");
            // const ws = new WebSocket("wss://nodejs-websocket-server-js.herokuapp.com");
    
            ws.onopen =
                () =>
                {
                    console.log("Connection");
                    ws.send(JSON.stringify({ msg: "Hello, server!" }));
                };
    
            ws.onmessage =
                (event) =>
                {
                    const msg = JSON.parse(event.data);
                    console.log(msg);
                };
    
        </script>
    </body>
    
    </html>
    

    You need to have these modules: express and ws. Do not forget to add "start": "node app.js" to package.json - it is for Heroku.

    package.json

    {
      "name": "nodejs-websocket-server-js",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1",
        "start": "node app.js"
      },
      "keywords": [],
      "author": "",
      "license": "ISC",
      "dependencies": {
        "express": "^4.17.1",
        "ws": "^7.3.1"
      }
    }
    

    Qt Client with SFML:

    NodeJSWebSocketClient_QtSFML_Qt5Cpp.pro

    QT       += core gui websockets
    
    INCLUDEPATH += "E:\Libs\SFML-2.5.1-mingw-32bit\include"
    LIBS += -L"E:\Libs\SFML-2.5.1-mingw-32bit\lib"
    LIBS += -lsfml-system -lsfml-graphics -lsfml-window
    
    greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    
    CONFIG += c++11
    
    # You can make your code fail to compile if it uses deprecated APIs.
    # In order to do so, uncomment the following line.
    #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
    
    SOURCES += \
        QSfmlWidget.cpp \
        main.cpp \
        MainWindow.cpp
    
    HEADERS += \
        MainWindow.h \
        QSfmlWidget.h
    
    # Default rules for deployment.
    qnx: target.path = /tmp/$${TARGET}/bin
    else: unix:!android: target.path = /opt/$${TARGET}/bin
    !isEmpty(target.path): INSTALLS += target
    

    MainWindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QtWebSockets/QWebSocket>
    
    #include "QSfmlWidget.h"
    
    class MainWindow : public QSfmlWidget
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = nullptr);
    
        void onInit() override;
        void onUpdate() override;
    
    private slots:
        void onConnected();
        void onMessageReceived(const QString &message);
    
    private:
        sf::RectangleShape m_rect;
        QWebSocket m_webSocket;
    };
    #endif // MAINWINDOW_H
    

    MainWindow.cpp

    
    #include <QtCore/QJsonDocument>
    #include <QtCore/QJsonObject>
    
    #include "MainWindow.h"
    
    MainWindow::MainWindow(QWidget *parent)
        : QSfmlWidget(parent)
    {
        setWindowTitle("Qt SFML WebSocket Client");
        setFixedSize(QSize(350, 350));
    
        connect(&m_webSocket, &QWebSocket::connected, this, &MainWindow::onConnected);
        connect(&m_webSocket, &QWebSocket::textMessageReceived, this, &MainWindow::onMessageReceived);
    
        QUrl url("ws://localhost:3000");
    //    QUrl url("ws://nodejs-websocket-server-js.herokuapp.com");
        m_webSocket.open(url);
    }
    
    void MainWindow::onInit()
    {
        m_rect.setPosition(50, 100);
        m_rect.setSize(sf::Vector2f(100, 50));
        m_rect.setFillColor(sf::Color::Green);
    }
    
    void MainWindow::onUpdate()
    {
        sf::RenderWindow::draw(m_rect);
    }
    
    void MainWindow::onConnected()
    {
        qDebug() << "Connection";
    
        // Send a message to a server
        QJsonObject jsonObject;
        jsonObject["msg"] = "Hello, server!";
        QJsonDocument doc(jsonObject);
        QString strJson(doc.toJson(QJsonDocument::Compact));
        m_webSocket.sendTextMessage(strJson);
    }
    
    void MainWindow::onMessageReceived(const QString &message)
    {
        qDebug() << message; // Output: "{\"msg\":\"Hello, client!\"}"
        QJsonDocument doc(QJsonDocument::fromJson(message.toUtf8()));
        QJsonObject data = doc.object();
        qDebug() << data["msg"].toString(); // Output: "Hello, client!"
    }
    

    QSfmlWidget.h

    #ifndef QSFMLWIDGET_H
    #define QSFMLWIDGET_H
    
    #include <QObject>
    #include <QTimer>
    #include <QWidget>
    #include <SFML/Graphics.hpp>
    
    class QSfmlWidget : public QWidget, public sf::RenderWindow
    {
        Q_OBJECT
    
    public:
        explicit QSfmlWidget(QWidget *parent = nullptr);
    
        virtual QPaintEngine * paintEngine() const override;
        virtual void showEvent(QShowEvent *event) override;
        virtual void paintEvent(QPaintEvent *event) override;
        virtual void onInit();
        virtual void onUpdate();
    
    private:
        QTimer m_timer;
        bool m_initialized;
    };
    
    #endif // QSFMLWIDGET_H
    

    QSfmlWidget.cpp

    #include "QSfmlWidget.h"
    
    QSfmlWidget::QSfmlWidget(QWidget *parent)
        : QWidget(parent)
        , m_initialized(false)
    {
        setAttribute(Qt::WA_PaintOnScreen);
        setAttribute(Qt::WA_OpaquePaintEvent);
        setAttribute(Qt::WA_NoSystemBackground);
    
        setFocusPolicy(Qt::StrongFocus);
    }
    
    QPaintEngine *QSfmlWidget::paintEngine() const
    {
        return nullptr;
    }
    
    void QSfmlWidget::showEvent(QShowEvent *event)
    {
        Q_UNUSED(event);
    
        if (!m_initialized)
        {
            sf::RenderWindow::create(reinterpret_cast<sf::WindowHandle>(winId()));
    
            onInit();
    
            connect(&m_timer, SIGNAL(timeout()), this, SLOT(repaint()));
            m_timer.start();
            m_initialized = true;
        }
    }
    
    void QSfmlWidget::paintEvent(QPaintEvent *event)
    {
        Q_UNUSED(event);
    
        RenderWindow::clear(sf::Color::White);
        onUpdate();
        RenderWindow::display();
    }
    
    void QSfmlWidget::onInit()
    {
        // To be overriden
    }
    
    void QSfmlWidget::onUpdate()
    {
        // To be overriden
    }
    

    main.cpp

    #include "MainWindow.h"
    
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
        return a.exec();
    }
    
    1 Reply Last reply
    0

    1/1

    7 Nov 2021, 09:30

    • Login

    • Login or register to search.
    1 out of 1
    • First post
      1/1
      Last post
    0
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Get Qt Extensions
    • Unsolved