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.
For some reason I keep getting "http://127.0.0.1:3000/socket.io/socket.io.js" 404 not found when I look under chrome developer tools network. I have spent over an hour trying to understand why this isn't working because it was working fine before and I didn't think I changed anything.
Server:
var express = require('express'),
session = require('express-session');
var app = express();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var MongoStore = require('connect-mongo')(session);
var sessionMiddleware = session({
resave: false,
saveUninitialized: false,
secret: 'secret',
store: new MongoStore({url: "mongodb://localhost:27017/database"})
});
app.use(sessionMiddleware);
io.use(sessionMiddleware, function(socket, next) {
sessionMiddleware(socket.request, socket.request.res, next);
});
io.sockets.on('connection', function (socket) {
console.log("Socket connected");
});
app.set('view engine', 'pug');
app.use(express.static(__dirname + '/public'));
app.get('/', function(req, res) {
res.render('index');
});
app.listen(3000);
console.log('listening');
Pug File:
html
head
script(src="http://127.0.0.1:3000/socket.io/socket.io.js")
script(type='text/javascript', src='../javascripts/chat.js')
body
Client javascript:
try {
var socket = io.connect('http://127.0.0.1:3000');
} catch(e) {
console.log(e);
}
Change this:
app.listen(3000);
to:
server.listen(3000);
app.listen() creates a new and different server so the server that you have socket.io attached to is not the one that is actually listening and thus your socket.io server is not live and not able to handle the /socket.io/socket.io.js request or the incoming connection if the script file didn't first fail to load.
See this answer for more details on what app.listen() does and why it isn't what you want the way your code is laid out:
websockets, express.js and can’t establish a connection to the server
Note, you could use app.listen(), but you'd have to not create your own server and you'd have to capture the return value from app.listen() and use that as the server you pass to socket.io initialization:
var app = express();
var server = app.listen(3000);
var io = require('socket.io')(server);
Which is not quite how your code is structured (but you could rearrange things to do it this way).
So I am new to express and io but I had a server running fine for webRTC but now there is a deprecated method in webRTC that only runs on https so I tried to create an https server but it starts and then immediately exits. I cannot figure out what is wrong and I do not get any errors. Also I am using an aws ec2 to run the express io server. Maybe someone can spot where in my syntax/implementation I am going wrong.
Note I have been googling around for the past half hour and cannot figure it out
Here is the code:
var connect = require('connect');
var https = require('https');
var fs = require('fs');
var express = require('express.io');
var app = express();
//app.http().io();
var PORT = 443;
var options = {
key: fs.readFileSync('../server.key'),
cert: fs.readFileSync('../server.crt')
};
app.https(options).io();
//var app = https.createServer(options, app1);
console.log('server started on port ' + PORT);
app.use(express.static(__dirname + '/public'));
app.get('/', function(req, res){
res.render('index.ejs');
});
app.listen(PORT);
app.io.route('ready', function(req) {
req.io.join(req.data.chat_room);
req.io.join(req.data.signal_room);
app.io.room(req.data).broadcast('announce', {
message: 'New client in the ' + req.data + ' room.'
})
})
Update
I am putting a bounty on this because I would like someone to provide me with a complete answer on setting up the server for production.
You need to add a rule for port 443 in a Security Group for your instance.
http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/authorizing-access-to-an-instance.html might help.
I'm using the Twit Node module with Node.js to try to track certain hashtags for an app I'm writing and I'm not getting anything out of the Api other than an error saying "Error: Bad Twitter streaming request". As far as I can tell I've followed the documentation but I'm obviously missing something.
Here is the code, with a few bits redacted:
var express = require('express');
var app = express();
app.set('view engine', 'ejs');
app.use(express.static('public'));
app.get('/', function(req, res) {
res.render('pages/index');
});
var http = require('http').createServer(app);
http.listen(80);
var io = require('socket.io').listen(http);
var twitterApi = require('twit');
var twitter = new twitterApi({
consumer_key: '***',
consumer_secret: '***',
app_only_auth: true
});
var stream = twitter.stream('statuses/filter', {track: '#twitter'});
stream.on('tweet', function(tweet){
console.log(tweet);
});
I'm working on an Ubuntu VM through Vagrant if that makes any difference?
Did you get the API credentials right ? 401 is usually returned with a unauthorized request, so I guess it must be with your API credentials.
You haven't provided access token and access token secret
I have no idea why this happens, but when I add a static path to my app I get an error on page of a hosting company I am using "nodejitsu" saying that application is not working, the line I am referring to is commented out in a code snippet below 'server.js' that is on the same level as my 'public' directory. I'm trying to think of a work around or other solution to define my public directory, but no luck so far, as I don't understand what could be causing an error. application uses node.js with dependencies including express and socket.io, latest versions.
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(80);
//app.use(express.static(__dirname + '/public'));
app.get('/', function(req, res) {
res.sendFile(__dirname + '/public/index.html');
});
io.on('connection', function (socket) {
});
The express term is not defined because you didn't save it.
You will need to do something like this:
var express = require('express');
var app = express();
app.use(express.static(__dirname + '/public'));