1

I am trying to make a browser multiplayer game using Socket.IO and Express, although it's not very clear for me why Express is needed. I have the app in my server, in a folder called /game so to access the app, the user should type http://www.example.com/game instead of http://www.example.com:3000 which is how the tutorial is doing it. I know this is more of an Apache 2 VirtualHost configuration file issue but I didn't know where to post it. Here is my actual .conf file

# /etc/apache2/sites-available/example.com.conf
<VirtualHost *:80>

ServerAdmin [email protected]
DocumentRoot /var/www/example.com/public_html
ServerName example.com
ServerAlias www.example.com
ProxyPreserveHost On
ProxyPass /game http://www.example.com:3000
ProxyPassReverse /game http://www.example.com:3000


ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>

Actually, when an user enters by typing the url with the port ( http://www.example.com:3000 ), the server returns a log message like 'user connected' BUT when I enter by typing the url I want ( http://www.example.com/game ) then it doesn't returns any message which is driving me crazy... index.js code:

var app = require('express')();
 var http = require('http').Server(app);
 var io = require('socket.io')(http);

 app.get('/', function(req, res){
   res.sendFile(__dirname + '/index.html');
 });

 io.on('connection', function(socket){
   console.log('a user connected');
   socket.on('disconnect', function(){
     console.log('user disconnected');
 });
 socket.on('chat message', function(msg){
    onsole.log('message: ' + msg);
 });
 });

 http.listen(3000, function(){
   console.log('listening on *:3000');
 });

index.html code:

<!doctype html>
<html>
  <head>
    <title>Socket.IO App</title>
    <style>
     * { 
       margin: 0;
       padding: 0; 
       box-sizing: border-box; 
     }
     body { 
       font: 13px Helvetica, Arial; 
     }
     form { 
       background: #000; 
       padding: 3px; 
       position: fixed;
       bottom: 0; 
       width: 100%; 
     }
     form input { 
       border: 0; 
       padding: 10px; 
       width: 90%; 
       margin-right: .5%; 
     }
     form 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>
    <ul id="messages"></ul>
    <form action="">
      <input id="m" autocomplete="off" /><button>Send</button>
    </form>
    <script src="/socket.io/socket.io.js"></script>
    <script src="https://code.jquery.com/jquery-1.11.1.js"></script>
    <script>
    $(function () {
      var socket = io();
      $('form').submit(function(){
        socket.emit('chat message', $('#m').val());
        $('#m').val('');
        return false;
      });
    });
    </script>
  </body>
</html>

Thanks in advance.

edit: Also, I have checked the browser console while accesing via example.com/game and it says the socket.io.js file is not found, but when entering the other way it does load the file correctly...

4
  • Hopefully this this will help: codingtricks.biz/run-nodejs-application-apache Commented Oct 22, 2017 at 1:42
  • 1
    Hi @MirzaSisic thanks for answer! It actually helped me but I have already seen that article and it doesn't solve my problem. Right now I can run my app and access it via example.com:3000 but I want to be able to access with example.com/game instead. Actually, both of them returns me to the correct page but when entering via example.com/game, it doesn't load the socket.io script (404) and the server doesn't returns any message as "an user connected". Thanks again! Commented Oct 22, 2017 at 1:58
  • When socket.io wasnt found, what is the url that is logged with it? And confirm if thats the correct url to your socket file Commented Oct 22, 2017 at 4:35
  • I was using a CDN url before. Now I have changed it to src="socket.io/socket.io.js" and now I don't get any error about the js file loading when requesting example.com/game but I get a 404 "polling-xhr.js:264 GET example.com/socket.io/… 404 (Not Found)" Commented Oct 22, 2017 at 14:09

1 Answer 1

1

On client side, specify the path field of socket.io client :

var socket = io('http://www.example.com', {
  'path': '/game/socket.io'
});

or :

var socket = io(window.location.origin, {
  'path': window.location.pathname + '/socket.io'
});

In your apache config, also add ws rewrite rule to route websocket traffic, you will need proxy, proxy_http, proxy_wstunnel and rewrite module :

RewriteEngine On
RewriteCond %{HTTP:Connection} Upgrade [NC]
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteRule /game/(.*) ws://www.example.com:3000/$1 [P,L]

ProxyPass        /game  http://www.example.com:3000
ProxyPassReverse /game  http://www.example.com:3000

You can find here a sample project using docker to reproduce your configuration (node app + apache reverse proxy)

Sign up to request clarification or add additional context in comments.

12 Comments

Hey thanks for answering! I will try this and come back with the results
Okey, I have tried a bunch of different things but none of them worked. Actually, when I enter example.com:3000 it loads the page correctly and logs a message in the server. But when i enter example.com/game it doesn't just dont log the message but also it doesn't load the socket.io file and also some script I have... I don't know if I am explaining myself too bad but this is driving me crazy
you should look at your browser dev console & apache logs to debug your issue
I am doing it currently, that's actually what I have said in the last comment, I can attach a picture if needed, the only error I have got is from the browser dev console stating that when entering via example.com/game it CAN'T load the socket.io file and neither execute a method in the onload event from the body element in my HTML file. I don't know how to check / test if my .conf file is correctly set up because if I type example.com/game it actually loads the HTML file but not the JS (index.js)
Replace /socket.io/socket.io.js with /game/socket.io/socket.io.js in client side
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.