bug on socket.io when run through application manager on cpanel?

Viewed 405

Hi,

After struggling A LOT, I finally was able to run socket.io on a shared hosting through cpanel application manager. It turns out that when registering the application you MUST leave the Base Application URL field empty, no matter what folder you plan to access your app from.

Lets say my domain is example.com and I want to install my chat on a folder called myapp so you can access it from here: example.com/myapp

As registering the app, you come across a filed that says:

Base Application URL: Enter the application’s base URL. After you register the application, you can use this URL to access it.

common sense tells you to enter "myapp" , right? Well, IGNORE that because if you enter anything else than a single / your socket.io app wont work. In order to be able to access it from the folder you want you must declare it within the app.js file like this:

app.get('/myapp', (req, res) => {  

then your app will work. However, notice that your ENTIRE DOMAIN will be now under the node.js, server, not only the folder where you access the app from which I dont think its right.

Is this a cpanel bug or a socket.io bug? Or am I missing something.

Thank you.

1 Answers

Okay, got it working on my side, here's my environment:

In cpanel, in the app registration menu:

Application URL: the actual directory you want the app to be accessible from , so you can indeed change it from "" to "myapp"

Actual required files:

  • public_html/.htaccess

    # DO NOT REMOVE. CLOUDLINUX PASSENGER CONFIGURATION BEGIN
    PassengerAppRoot "<root>/myapp"
    PassengerBaseURI "/myapp"
    PassengerNodejs "<root>/nodevenv/myapp/10/bin/node"
    PassengerAppType node
    PassengerStartupFile app.js
    # DO NOT REMOVE. CLOUDLINUX PASSENGER CONFIGURATION END
    # DO NOT REMOVE OR MODIFY. CLOUDLINUX ENV VARS CONFIGURATION BEGIN
    <IfModule Litespeed>
    </IfModule>
    # DO NOT REMOVE OR MODIFY. CLOUDLINUX ENV VARS CONFIGURATION END
    

(Note: <root> is the path up to "public_html" on my web host)

  • public_html/myapp/index.html (this is the file to be served to the client by the server, see server file further below)

    <!doctype html>
    <html>
    <head>
    <title>Socket.IO chat</title>
    <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body { font: 13px Helvetica, Arial; }
    #chat { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
    #chat input { border: 0; padding: 10px; width: 90%; margin-right: 0.5%; }
    #chat button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
    #messages { list-style-type: none; margin: 0; padding: 0; }
    #messages li { padding: 5px 10px; }
    #messages li:nth-child(odd) { background: #eee; }
    </style>
    </head>
    <body>
    <h1>Socket.IO Chat Test</h1>
    <ul id="messages"></ul>
    <div id='chat'>
    <input id="m" autocomplete="off" /><button id='submit'>Send</button>
    </div>
    <script src="/socket.io/socket.io.js"></script>
    <script>
    var submit = document.getElementById('submit');
    var m = document.getElementById('m');
    
    var socket = io();
    submit.onclick = function(e){
        socket.emit('data', {message: m.value});
        m.value = '';
        return false;
    };
    socket.on('data', function(msg){
        console.log(msg);
        if(msg.message){
            var e = document.createElement('li');
            e.innerHTML = msg.message;
            document.getElementById('messages').appendChild(e);
        }
    });
    </script>
    </body>
    </html>
    

(note: Make sure you have this /socket.io/socket.io.js path. You do not need to have a socket.io folder with the socket.io.js file next to index.html, this will be fetched as part of the socket.io dependency)

Lastly, your server file, which should be under "myapp" in your <root> directory:

  • <root>/myapp/app.js
    const port = 3000;
    var app = require('express')();
    var http = require('http').createServer(app);
    var io = require('socket.io')(http);
    
    app.get('/', (req, res) => {
        res.sendFile(__dirname + '/index.html');
    });
    
    io.on('connection', (socket) => {
        socket.on('data', (msg) => {
            console.log(msg);
            io.emit('data', msg);
        });
    });
    
    http.listen(port, () => {
        console.log('listening on *:' + port);
    });
    

(note: the important part here is that I've left "/" for the app.get function)

Let me know if you need more information!

Related