Форум программистов, компьютерный форум, киберфорум
8Observer8
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  

Инструкция по развёртыванию Node.js сервера с WebSockets на бесплатном хостинге Heroku. Веб-клиент и Desktop-клиент (Qt)

Запись от 8Observer8 размещена 17.12.2021 в 07:47
Показов 2475 Комментарии 1
Метки heroku, node.js, qt

Содержание блога

Heroku удалил бесплатный хостинг в ноябре 2022. Есть альтернативы, например:
  • https://glitch.com/pricing - даётся 1000 часов на месяц. Файлы проектов будут открыты всем пользователям. Если к приложению не обращаются 5 минут, оно засыпает и просыпается в течение 30 секунду: "Это может привести к задержке ответа до 30 секунд для первого запроса, поступающего после периода бездействия.". Есть бесплатная база данных SQLite.
  • У хостинга Render ограничение на бесплатное использование 750 часов в месяц: https://render.com/docs/free. После 15 минут неактивности засыпает. Бесплатная база данных PostgreSQL удаляется через 90 дней. Есть возможность разместить SQLite.
  • Подборка бесплатных хостингов для баз данных



Инструкция по развёртыванию Node.js сервера с WebSockets на бесплатном хостинге Heroku. Веб-клиент и Desktop-клиент (Qt)

Рабочий пример: https://mouse-click-js.herokuapp.com/ в котором координаты клика мыши отправляются на сервер и возвращается ответ клиенту в виде сообщения, которое он выводит на экран.

Инструкция по развёртыванию сервера на Heroku:
  • На сайте Heroku в правом верхнем углу выбрать "New" -> "Create new app":
  • Набрать имя игры и выбрать регион для сервера и нажать кнопку "Create app":
  • На вкладке "Deploy" нажать кнопку "Connect to GitHub":
  • Появится поле, где нужно ввести имя репозитория, нажать "Search":
  • Появится кнопка "Deploy Branch", которая загружает приложение из GitHub, либо можно нажать кнопку "Enable Automatic Deploy", которая активирует автоматическую загрузку из GitHub всякий раз, когда вы делаете у себя на компьютере "git push"
  • Приложение будет развёрнуто и у вас будет ссылка на приложение

Примечание. Бесплатный хостинг на Heroku имеет ограничения. Например, если к серверу не было обращений в течение 30 минут, то он засыпает. При следующем обращении отклик будет получен через 5-10 секунд, которые требуются, чтобы разбудить сервер. База данных MySQL имеет ограничение 5 МБайт. На сайте Heroku можно ознакомиться с другими ограничениями бесплатного аккаунта.

Исходники сервера + веб-клиента на JavaScript: https://github.com/8Observer8/mouse-click-js

app.js

JavaScript
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
const express = require("express");
const http = require("http");
const ws = require("ws");
const path = require("path");
 
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 connected");
        ws.onmessage =
            (event) =>
            {
                const msg = JSON.parse(event.data);
                console.log(msg.x + ", " + msg.y);
                // Send an answer
                const resp = {
                    x: msg.x,
                    y: msg.y
                }
                ws.send(JSON.stringify(resp));
            }
    });
 
const port = process.env.PORT || 3000;
httpServer.listen(port, () => { console.log("Server started. Port: ", port); });
public/index.html

PHP/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
38
<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Web Client</title>
</head>
 
<body>
    <h3>Click on the window.</h3>
    <div id="output" style="font-family: Arial; font-size: 14px;"></div>
 
    <script>
        const output = document.getElementById("output");
        output.innerHTML = "Wait for connection...";
        // const ws = new WebSocket("ws://localhost:3000");
        const ws = new WebSocket("wss://mouse-click-js.herokuapp.com");
        ws.onopen =
            () => {
                output.innerHTML = "Connected to the server";
                window.onclick = (event) => {
                    const x = event.clientX;
                    const y = event.clientY;
                    console.log(x + ", " + y)
                    ws.send(JSON.stringify({x: x, y: y}));
                };
 
                ws.onmessage = (event) => {
                    console.log(event.data);
                    const msg = JSON.parse(event.data);
                    output.innerHTML = `Answer from server: x = ${msg.x}, y = ${msg.y}`;
                }
            };
    </script>
</body>
 
</html>
package.json

JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
  "name": "mouse-click-js",
  "version": "1.0.0",
  "description": "",
  "main": "app.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 C++: https://github.com/8Observer8/... ent_Qt5Cpp

main.cpp

C++ (Qt)
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>
#include <QtWidgets/QLabel>
#include <QtWidgets/QVBoxLayout>
#include <QtGui/QMouseEvent>
#include <QtWebSockets/QWebSocket>
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonObject>
#include <QtCore/QDebug>
 
class Window : public QWidget {
    Q_OBJECT
private:
    QWebSocket m_webSocket;
    QLabel m_connection;
    QLabel m_output;
public:
    Window(QWidget *parent = nullptr) : QWidget(parent) {
        setWindowTitle("Qt C++ Client");
        resize(300, 300);
        QVBoxLayout *vbox = new QVBoxLayout(this);
        QLabel *instruction = new QLabel("Click on the window.");
        m_connection.setText("Wait for connection...");
        QFont font = QFont("Arial", 14);
        instruction->setFont(font);
        m_connection.setFont(font);
        m_output.setFont(font);
        vbox->addWidget(instruction);
        vbox->addWidget(&m_connection);
        vbox->addWidget(&m_output);
        vbox->addStretch(1);
        connect(&m_webSocket, &QWebSocket::connected,
                 this, &Window::onConnected);
        // m_webSocket.open(QUrl("ws://localhost:3000"));
        m_webSocket.open(QUrl("wss://mouse-click-js.herokuapp.com"));
    }
private slots:
    void onConnected() {
        m_connection.setText("Connected to server");
        connect(&m_webSocket, &QWebSocket::textMessageReceived,
                this, &Window::onMessageReceived);
    }
    void onMessageReceived(QString message) {
        qDebug() << message;
        QJsonDocument doc(QJsonDocument::fromJson(message.toUtf8()));
        QJsonObject data = doc.object();
        int x = data["x"].toInt();
        int y = data["y"].toInt();
        // Show data
        m_output.setText(QString("Answer from server: %1, %2").arg(x).arg(y));
    }
private:
    void mousePressEvent(QMouseEvent *event) override {
        Q_UNUSED(event);
        qDebug() << event->x() << " " << event->y();
        QJsonObject jsonObject;
        jsonObject["x"] = event->x();
        jsonObject["y"] = event->y();
        QString message = QJsonDocument(jsonObject).toJson(QJsonDocument::Compact);
        m_webSocket.sendTextMessage(message);
    }
};
 
#include "main.moc"
 
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Window w;
    w.show();
    return a.exec();
}
MouseClick_QtClient_Qt5Cpp.pro

Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
QT       += core gui websockets
 
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 += \
    main.cpp
 
HEADERS +=
 
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
Вложения
Тип файла: zip mouse-click-js-master.zip (2.1 Кб, 445 просмотров)
Тип файла: zip MouseClick_QtClient_Qt5Cpp-master.zip (2.0 Кб, 476 просмотров)
Метки heroku, node.js, qt
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 1
Комментарии
  1. Старый комментарий
    Heroku удалил бесплатный хостинг в ноябре 2022. Есть альтернативы, например:
    • https://glitch.com/pricing - даётся 1000 часов на месяц. Файлы проектов будут открыты всем пользователям. Если к приложению не обращаются 5 минут, оно засыпает и просыпается в течение 30 секунду: "Это может привести к задержке ответа до 30 секунд для первого запроса, поступающего после периода бездействия.". Есть бесплатная база данных SQLite.
    • У хостинга Render ограничение на бесплатное использование 750 часов в месяц: https://render.com/docs/free. После 15 минут неактивности засыпает. Бесплатная база данных PostgreSQL удаляется через 90 дней. Есть возможность разместить SQLite.
    • Подборка бесплатных хостингов для баз данных

    Запись от 8Observer8 размещена 06.10.2022 в 15:16 8Observer8 вне форума
 
Новые блоги и статьи
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Nekobox - outbounds[0].transport: unknown transport type: raw
damix 01.10.2026
Фикс ошибки Правым кликом по серверу -> отладочная информация -> edit Заменить "net": "raw", на "net": "tcp", Нажать кнопку reload.
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru