nodejs socket.io GET http://domain/socket.io/?EIO=

2019-09-20 13:30发布

问题:

My problem is simple I'm actually getting an error 404 when I'm trying to import socket.io on my web page. I'm using

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>

to import socket.io.

If I remove this line form my head tag, I'm fine but when it's there, I see in the dev tool the 404 error and my counter is not even working.

I am trying to make a live viewer count for one of my website but I never really use Node.js so this is why I have some trouble. Please forgive me if there is an error in my script.

For the serverside script, the file is called: viewercounter.js and this is the code

var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var port = 8001;

server.listen(port, function () {
  console.log('Server listening at port %d', port);
});

app.use(express.static(__dirname + '/public'));

var count = 0
io.on('connection', function(socket) {
    count++;
    socket.broadcast.emit('userupd', {
        numUsers: count
    });
    console.log(count);

    socket.on('disconnect', function(){
        count--;
        socket.broadcast.emit('userupd', {
            numUsers: count
        });
        console.log(count);
    });
});

Then I placed the clientside script directly in my page instead of making a new file, I did not really see the point of it. Anyway, the file is called: index.php and the code is at the end of the file just before the end of the body tag and there not other js before the code.

<script type="text/javascript">
$(function() {
  var socket = io();

  socket.on('userupd', function (data) {
    $('.counter').html(data);
  });
});

EDIT

By looking more deeper, I've been able to understand that it's a XMLHttpRequest problem. In fact, when the socket.io code that I just imported try to perform xhr.send(this.data) the error appears. Anyone knows how I can solve this ? https://gyazo.com/53f64081a92b449e157df76c6c570178

EDIT2

After changing the port in the file viewcounter.js. It looks like this:

// Setup basic express server
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var port = 80;

server.listen(port, function () {
  console.log('Server listening at port %d', port);
});

// Routing
app.use(express.static(__dirname + '/public'));

var count = 0
io.on('connection', function(socket) {
    count++;
    socket.broadcast.emit('userupd', {
        numUsers: count
    });
    console.log('New user: ');

    socket.on('disconnect', function(){
        count--;
        socket.broadcast.emit('userupd', {
            numUsers: count
        });
        console.log('Neg user:');
    });
   });

回答1:

If your web page is coming from an Apache web server on port 80 and you want to create a socket.io server in node.js on the same host, then you need to pick a new port for that socket.io server and when you connect to the socket.io server, you need to identify the port you want to connect to because the default will be port 80, but that's not where your socket.io server is.

I'd suggest using port 8001 like you originally had for your socket.io server. Please change your node.js code back to that.

Then, you can change the socket.io code in your page from this:

<script type="text/javascript">
$(function() {
  var socket = io();

  socket.on('userupd', function (data) {
    $('.counter').html(data);
  });
});
</script>

to this:

<script type="text/javascript">
$(function() {
  var url = window.location.protocol + "//" + window.location.hostname + ":8001";
  var socket = io(url, {transports: ['websocket'], upgrade: false});

  socket.on('userupd', function (data) {
    $('.counter').html(data);
  });
});
</script>

This will connect socket.io to the same protocol and host as your web page, but a different port and it will use only a webSocket so you don't run into cross origin issues with socket.io's usual attempt to initiate a connection with Ajax polling.

If your socket.io server is actually on a different host than your Apache server, then you need to put that host in the URL rather than window.location.hostname.