简体   繁体   中英

Socket.io http://localhost:3000/socket.io/socket.io.js 404 (Not Found) - How to configure socket.IO - nodejs, apache2, websockets

Ok im having problems yet again with socket.io and express. When I run my node js application it begins to build before hitting an error " GET http://localhost:3000/socket.io/socket.io.js 404 (Not Found) " and "Uncaught ReferenceError: io is not defined" This is my second time working with web sockets and receiving the same error. For the previous app I fixed this problem by setting up a reverse proxy on my apache server. It looked like this;

ProxyPass /socket.io http://localhost:3000/socket.io

However for current nodejs app this is not fixing the issue. The main difference between these two applications is that the current app does not start working with socket.io until the user directs themself to the localhost:3000/bomber-kids-online game page. The current app is an extension of the first app aka this nodejs app provides a website along with my previous app which is a game hosted at zEyeland.com/bomber-kids-online.

Here is a look at my js file that sends the browser the proper html file to load:

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

var updatedMAP;
var updatedOBJECTS;

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

io.on('connection', function(socket){
  console.log("a user connected");

  socket.on('sendNoramlBomb', function(xPosition, yPosition, power){

  socket.broadcast.emit('sendNoramlBomb', xPosition, yPosition, 
power);
  });
  socket.on('sendRedBomb', function(xPosition, yPosition, power){

    socket.broadcast.emit('sendRedBomb', xPosition, yPosition, power);
});
  socket.on('sendBlueBomb', function(xPosition, yPosition, power){

    socket.broadcast.emit('sendBlueBomb', xPosition, yPosition, 
power);
  });
  socket.on('sendGreyBomb', function(xPosition, yPosition, power){

    socket.broadcast.emit('sendGreyBomb', xPosition, yPosition, 
power);
  });
  socket.on('sendGreenBomb', function(xPosition, yPosition, power){

    socket.broadcast.emit('sendGreenBomb', xPosition, yPosition, 
power);
  });

  socket.on('sendPlayer', function(locationY, locationX, direction){


    io.emit('sendPlayer',locationY, locationX, direction);
  });

  socket.on('chat message', function(msg){
   io.emit('chat message', msg);
 });

 socket.on('disconnect', function(){
   console.log("user disconnected");
     });
   });

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

module.exports = router;

This is the apache configuration for my current project

    ProxyPass        /socket.io http://localhost:3000/bomber-kids-online/socket.io
    ProxyPassReverse /socket.io http://localhost:3000/bomber-kids-online/socket.io


    <Proxy *>
        Order deny,allow
    Allow from all 
    </Proxy>    
ProxyRequests Off
ProxyPreserveHost On

ProxyPass    / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/

So to recap on whats going on. Im trying to run a nodejs game that uses websockets. When visit my game on website at localhost:3000/bomber-kids-online it get an ( GET http://localhost:3000/socket.io/socket.io.js 404 (Not Found) ) How do i fix this issue? My reverse proxy will not seem to fix it this time. You can view a working version of my game at zeyeland.com/bomber-kids-online. My current project uses the exact same html and javascript files to run. However by examining my reverseProxy above you will notice that in my current project the game is not being accessed from localhost:3000 directly but from a route which is provided from another js file on server.

Here is how my app first js file looks like;

 var createError = require('http-errors');
 var express = require('express');
 var path = require('path');
 var cookieParser = require('cookie-parser');
 var logger = require('morgan');

 var indexRouter = require('./routes/index');
 var usersRouter = require('./routes/users');
 var bomberKidsRouter = require('./routes/games/bomber-kids-online- 
game');

 var app = express();

 // view engine setup
 app.set('views', path.join(__dirname, 'views'));
 app.set('view engine', 'pug');

 app.use(logger('dev'));
 app.use(express.json());
 app.use(express.urlencoded({ extended: false }));
 app.use(cookieParser());
 app.use(express.static(path.join(__dirname, 'public')));

 app.use('/', indexRouter);
 app.use('/users', usersRouter);
 app.use('/bomber-kids-online', bomberKidsRouter);

 // catch 404 and forward to error handler
 app.use(function(req, res, next) {
 next(createError(404));
 });

 // error handler
 app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
 res.locals.error = req.app.get('env') === 'development' ? err : {};

 // render the error page
 res.status(err.status || 500);
res.render('error');
 });

 module.exports = app;

The issue is that express and socket.io are not sharing the same server. I'm not seeing any server.listen so I will guess that socket.io isn't even listening on any port.

You're getting that error, because http://localhost:3000/socket.io/socket.io.js is being served by express and of course you don't have that route setup (And you shouldn't do it).

The fix is to attach the express server to socket.io

index.js

const app = express();

const server = require('http').Server(app);
const io = require('socket.io')(server); // Pass server to it instead of port

// Now you can pass `io` to any file you want, and setup your socket logic
// Do the same for express app.
// Or handle the logic here, whatever you prefer

server.listen(3000); // Listen

You can do that, or use a different port for socket.io .

Could you further explain or point me to documentaion about how socket.io works, why it can not run on same port as my node app

You can't have to applications, or server listening on the same port, otherwise you will get: Error: listen EADDRINUSE

That's why if you wish to use express & socket.io on the same port, you have to use the same server listening on that specific port for both.

I was having this same issue and followed these steps sugested by @Marcos but it didn't work in my case, so I removed all the socket.io, socketio and express packages I had, reinstalled as the following

npm i express --save
npm i socket.io@2.4.1 --save

and made sure they were updated, as before Ubunto was downloading the 2.1 ver of socket.io and it had a few vulnerability issues, then instead of using the 'require' format I used 'import' as follows

import express from 'express';
import http from 'http';
import createGame from './public/game.js';
import socketio from 'socket.io';

const app = express();
const server = http.createServer(app);
const sockets = socketio(server);

and it finally worked. After struggling with this all day I thought this would be helpfull if someone have a similar issue in the future.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM