Reputation: 65
I made the "Getting started" example of socket.io, it works perfectly on localhost on my computer. But when I upload it to my hosting it is not working, the client throws a 404 error trying to get socket.io.js:
<script src="/socket.io/socket.io.js"></script>
I solved this with this other reference (I didn't need to do this on localhost):
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/socket.io.js"></script>
But then, I am getting 404 errors constantly when the client is running on the hosting. It seems like Node.js server is not running on server and not serving socket.io files when is on hosting. I don't get these 404 errors when I am on localhost. There is an example of this calls:
GET http://localhost/socket.io/?EIO=3&transport=polling&t=MMc5E4X
(200 works fine on local)
GET http://tinatest.gearhostpreview.com/socket.io/?EIO=3&transport=polling&t=MMc5E4X
(404)
I got this example on a free Node.js hosting so you can have a look at it, I activated Node.js 8 on this server and this is running on port 80:
http://tinatest.gearhostpreview.com/
The files on the server are:
Index.html
<!doctype html>
<html>
<head>
<title>Socket.IO chat</title>
<style>
</style>
</head>
<body>
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="off" /><button>Send</button>
</form>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/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;
});
socket.on('chat message', function(msg){
$('#messages').append($('<li>').text(msg));
});
});
</script>
</html>
Index.js
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){
socket.on('chat message', function(msg){
io.emit('chat message', msg);
});
});
http.listen(80, function(){
console.log('listening on *:80');
});
package.json
{
"name": "socket-chat-example",
"version": "0.0.1",
"description": "my first socket.io app",
"dependencies": {
"express": "^4.15.2",
"socket.io": "^2.1.1",
"socket.io-client": "^2.1.1"
}
}
How can I make this work? Or if not, why is it not possible?
Upvotes: 1
Views: 1298
Reputation: 65
As i was thinking all the time the problem was i was not running any node server. I followed these steps, in my case that i was on a free not dedicated hosting (no remote desktop), I used VS Code:
node index
in localhost:8080 with Code cmd.VPS_IP_ADRESS:8080
C:\inetpub\wwroot
)Now everything works perfectly in my VPS IP in any device. I can chat between my devices. I used IIS for the client because i use to publish there. I think i can´t do this in my old hosting in any way since i ask for Node support and they told me they don´t have. Ubuntu VPS should be a cheaper option but that is to much for me now. If you have expiernce with Node + Ubuntu server, you should try.
Upvotes: 0
Reputation: 3515
Think about what a Node.js
+ express
server does. Among many things, it can serve files based on various types of http requests. However, you have to tell it exactly what types of requests to listen for (GET
, POST
, etc.) and on what routes (/
, /folder
). You can even listen for query strings, params, bodies of post messages, etc, etc. However, its up to you to define them.
Look over your code, what route have your defined?
Just one: /
and you allow a GET
requests to that route and in response you are serving index.html
, which has all of your front-end logic, at least in this case.
If you were to try to GET
other routes, like /socket.io/
you will by default get a 404 error.
The script file you mention has as it's src
value /socket.io
, since you don't have a route to serve the socket.io code, it fails in production.
On localhost, if the files are available in the same project, your browser can resolve the relative path on your local machine. Once the project is deployed, the relative paths are no longer looking to your machine but hitting your router with a full blown url. It's expecting those files to be served.
You can solve the problem in production by giving a full url reference to the necessary socket.io
code.
MORE: An Example:
index.js
- see comments below
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
/**
* Your ROUTES
* in production, when someone goes to http://tinatest.gearhostpreview.com/
* they are calling your root route "/"
* Your callback function is sending back index.html from your root directory
* You add __dirname because you don't know where gearhost is actually putting
* your stuff.
*
* In production, you can only access server-side files if you serve them
*/
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
/**
* ONE WAY TO SERVE JS TO YOUR CLIENT
* (there are many better ways of doing this)
*
* If you do this, you will not get a 404 error
*/
app.get('/socket.io/socket.io.js', function(req, res){
// this assumes you have a folder within your root named socket.io
// and that it contains socket.io.js,
res.sendFile(__dirname + '/socket.io/socket.io.js');
})
io.on('connection', function(socket){
socket.on('chat message', function(msg){
io.emit('chat message', msg);
});
});
http.listen(80, function(){
console.log('listening on *:80');
});
index.html
- only looking at scripts
<!--
The src is the URI of an external script, that is,
a script external to this particular document.
Below, the URIs are absolute paths for getting for files hosted by other services.
-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<!--
You can also use relative paths.
If your src value is /socket.io,
then your page looks for a file
relative to the current location of itself.
On localhost, your page has access to files within its own folder
-->
<script src="/socket.io/socket.io.js"></script>
<!--
HOWEVER, in production, you cannot use relative paths
UNLESS you are serving your files either as static assets
via middleware (http://expressjs.com/en/guide/using-middleware.html)
OR via a public route (http://expressjs.com/en/4x/api.html#app.use)
You are getting a 404 in production because you aren't serving
assets.
BUT!!! you can always use an external 3rd party service
-->
Upvotes: 1