简体   繁体   中英

Socket IO works fine on local machine but doesn't work on Heroku

Situation:

I'm building an web app (a SPA) with ReactJS and ExpressJS. I'm using Socket.IO for real-time chatting. When I build my app and run it on localhost, everything works fine so I decide to deploy it on Heroku. My app is built successfully on Heroku and ready to use.

Problem:

So I enter my app to see if it works fine on Heroku. The app seems to be ok when I enter login page and register page (these pages are not going with Socket.IO). But when I go to chat page (this page is using Socket.IO for real-time chatting), the client is crashed, it's not loaded and throw the below error.

Error:

I get this following error:

> 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)

When I look at the module online, it has the following check:

// 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
  }

So I start my app on localhost and search for above code, I get this:

// 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;
  }

Code:

This is my server:

//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.log("Server started on: " + port);

My socket setup:

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

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

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

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

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

module.exports = socket;

React component that using 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 */
    );
};

What I want:

I want to know if there is any problem with my code. When I deploy my app to Heroku, is there any extra setup I have to do on Heroku to make my app working with Socket.IO?

The problem is not in the code you have pasted, or at least I doubt it. If you look at the module online, you see it has the following check:

    // 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;
    }

You will notice it's reading it off process.env , this is a Node thing / Electron thing. Inside of the console of your client, type window.process , if you get something, that's probably it. It's inspecting process ... probably webpack

After spending hours researching and reviewing my code, I have figured out why my app is not working on Heroku. That because the client using dotenv module, and I setup it in 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)
        })
    ]
};

Then when I deploy my app on Heroku, Heroku will build my client from source code and server will look for the frontend part in dist folder. The client now can't find the .env file on Heroku so it can't load the environment variables that causes it to throw error.

I removed dotenv because I don't need it now.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM