Socket IO отлично работает на локальной машине, но не работает на Heroku

Ситуация:

Я создаю веб-приложение (SPA) с ReactJS и ExpressJS. Я использую Socket.IO для общения в реальном времени. Когда я создаю свое приложение и запускаю его на локальном хосте, все работает нормально, поэтому я решаю развернуть его на Heroku. Мое приложение успешно построено на Heroku и готово к использованию.

Проблема:

Поэтому я захожу в свое приложение, чтобы посмотреть, нормально ли оно работает на Heroku. Кажется, что с приложением все в порядке, когда я захожу на страницу входа и страницу регистрации (эти страницы не идут с Socket.IO). Но когда я перехожу на страницу чата (эта страница использует Socket.IO для общения в реальном времени), клиент аварийно завершает работу, он не загружается и выдает следующую ошибку.

Ошибка:

Я получаю следующую ошибку:

> Uncaught TypeError: Cannot read property 'DEBUG' of undefined
    at load (browser.js:168)
    at Object.eval (browser.js:178)
    at eval (browser.js:197)
    at Object../node_modules/socket.io-client/node_modules/debug/src/browser.js (vendor.js:2639)
    at __webpack_require__ (main.js:788)
    at fn (main.js:151)
    at eval (url.js:7)
    at Object../node_modules/socket.io-client/lib/url.js (vendor.js:2628)
    at __webpack_require__ (main.js:788)
    at fn (main.js:151)

Когда я смотрю на модуль онлайн, у него есть следующая проверка:

// If debug isn't set in LS, and we're in Electron, try to load $DEBUG
  if (!r && typeof process !== 'undefined' && 'env' in process) {
    r = undefined.DEBUG; //the error is showed here
  }

Итак, я запускаю свое приложение на локальном хосте и ищу приведенный выше код, я получаю следующее:

// If debug isn't set in LS, and we're in Electron, try to load $DEBUG
  if (!r && typeof process !== 'undefined' && 'env' in process) {
    r = { /*A JSON object contains .env variables*/ }.DEBUG;
  }

Код:

Это мой сервер:

//requirements...
const socket = require("./server/socket");

const app = express();
const server = http.createServer(app);
const port = process.env.PORT || 3000;

//middlewares...
//routes...
//database connection...

socket(server);

server.listen(port);
console.info("Server started on: " + port);

Моя настройка сокета:

const socketIO = require("socket.io");

const socket = server => {
    const io = socketIO(server);
    const chat = io.of("/chat");

    chat.on("connection", client => {
        console.info("User started chat!");

        client.on("disconnect", () => {
            console.info("User left chat!");
        });

        client.on("sendMessage", msg => {
            const data = msg;
            client.broadcast.emit("incomingMessage", { data });
        });
    });
};

module.exports = socket;

Компонент React, использующий Socket.IO:

const _ChatBox = ({ props }) => {
    const [connection] = useState(io("/chat"));

    useEffect(() => {
        connection.on("incomingMessage", message => {
            //receive message...
        });
    }, []);

    const sendMessageToSocket = data => {
        connection.emit("sendMessage", data);
    };

    return (
        /* JSX here */
    );
};

Что я хочу:

Я хочу знать, есть ли какие-либо проблемы с моим кодом. Когда я развертываю свое приложение в Heroku, нужно ли мне выполнять какие-либо дополнительные настройки в Heroku, чтобы мое приложение работало с Socket.IO?

Что рушится? Сервер или клиент?

Vaughan Hilts 27.05.2019 03:50

@VaughanHilts клиент

Trí Phan 27.05.2019 03:55
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
4
2
1 240
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Проблема не в коде, который вы вставили, или, по крайней мере, я в этом сомневаюсь. Если вы посмотрите на модуль онлайн, вы увидите, что он имеет следующую проверку:

    // If debug isn't set in LS, and we're in Electron, try to load $DEBUG
    if (!r && typeof process !== 'undefined' && 'env' in process) {
        r = process.env.DEBUG;
    }

Вы заметите, что он считывает это process.env, это вещь Node / вещь Electron. Внутри консоли вашего клиента введите window.process, если вы что-то получили, возможно, это оно. Он проверяет process... возможно, веб-пакет

Я получаю это r = undifined.DEBUG; вместо r = process.env.DEBUG;

Trí Phan 27.05.2019 04:34

Для window.process?

Vaughan Hilts 27.05.2019 04:36

да, когда я набираю window.process, он возвращает undefined

Trí Phan 27.05.2019 04:37
Ответ принят как подходящий

Потратив несколько часов на изучение и просмотр своего кода, я понял, почему мое приложение не работает на Heroku. Это потому, что клиент использует модуль dotenv, а я настроил его в webpack.config.js:

//...requirements
const dotenv = require("dotenv");
const webpack = require("webpack");

module.exports = {
    //...configs
    plugins: [
        //...other plugins
        new webpack.DefinePlugin({
            "process.env": JSON.stringify(dotenv.parsed)
        })
    ]
};

Затем, когда я разверну свое приложение на Heroku, Heroku соберет мой клиент из исходного кода, а сервер будет искать интерфейсную часть в папке dist. Клиент теперь не может найти файл .env на Heroku, поэтому он не может загрузить переменные среды, из-за которых он выдает ошибку.

Я удалил dotenv, потому что он мне сейчас не нужен.

Другие вопросы по теме