I am attempting to develop an online browser game, and though I have no intention of buying a domain or cloud hosting it, I want to be able to run a server on my computer and have people play the online game by connecting via browser on other devices, on other networks. I have developed the game using socket-io, express, and phaser, and I have reached the point where I can play the game, with full multiplayer functionality between different tabs on the computer running the server. I am struggling to figure out the code and port forwarding changes to make it work over the public internet.
Reducing it to the bare bones, I have a server.js file in the root as follows:
const server = require('express')();
const http = require('http').createServer(server);
const host = 'localhost'; const port = 3000;
const io = require('socket.io')(http, {
cors: { origin: `http://${host}:8080` }
});
io.on('connection', function (socket) {
console.log('A user connected: ' + socket.id);
socket.on('disconnect', function () { console.log('A user disconnected: ' + socket.id); });
});
http.listen(port, host, function () {
console.log('Server started!');
});
And in a client directory there is a index.html that calls the following game.js script:
import io from 'socket.io-client';
const hostname = 'localhost'; const port = 3000;
let serverAddress = `http://${hostname}:${port}`;
export default class Game extends Phaser.Scene {
constructor() {
super({ key: 'Game' });
}
create() {
this.socket = io(serverAddress);
this.socket.on('connect', function () { console.log('Connected!'); });
}
}
From these, I run npm start
in both the root and client directories. When opening http://localhost:8080/
in a browser I get an acknowledgement by the server process that a user connects, and an acknowledgement in the browser console that the webpage is connected.
I have tried port forwarding to make sure that socket-io can send and receive publicly. I don’t have a router but I going to my modem settings I added ipv4 forwarding for the port 3000
and my PC’s local ip (10.0.0.58
) with TCP and UDP. I can’t really get my head around the relationship between port forwarding, the ports 3000
and 8080
, and the Nodejs server and client processes.
I have tried changing in the code to replace localhost with my public ipv4 address (xxx.xxx.xxx.234
), which whatismyipaddress.com reckons is probably static, but the server console identifies http.listen() as throwing an error so this doesn’t get off the ground, and this happens even with Windows Defender Firewall disabled. No matter what I set the ports or the hosts to in server.js and game.js, when I open another device on a separate network and enter xxx.xxx.xxx.234
or xxx.xxx.xxx.234:3000
or xxx.xxx.xxx.234:8080
or anything I can’t get any connection.
What do I change to get it working? When using a browser on another device and network, should I expect to be connecting on xxx.xxx.xxx.234:8080
or xxx.xxx.xxx.234:3000
and why? Why does the browser on my local machine not load my game at xxx.xxx.xxx.234:3000
, but it does at xxx.xxx.xxx.234:8080
despite the fact that 8080 doesn’t appear anywhere in my code other than a cors fix? I’m sure I’m missing something obvious here because I’m just a self taught hobbyist, but it’d be great to figure this out so I can get back to coding the game!
2
Answers
So it turned out that the issue was my ISP, (Belong), which does not offer static IPs, uses CGNAT, and does not offer ipv6. I ended up getting it working after a lot of hair pulling by following this tutorial very closely:
https://www.reddit.com/r/selfhosted/comments/u8n5hz/how_to_bypass_cgnat_and_expose_your_server_to_the/
well this is no phaser issue this is more a Network issue/ question. That said, for others to be able to play the game, there are somethings you need too look out for:
So now specific to your question,