7

As stated in title, I'm trying to use socket.io 1.0.4 with express 4.2, and all /?EIO requests return 404.

Bellow there are my files:

./bin/www :

#!/usr/bin/env node
var debug = require('debug')('generated-express-app');
var app = require('../app');

app.set('port', process.env.PORT || 3000);

var server = app.listen(app.get('port'), function() {
  debug('Express server listening on port ' + server.address().port);
});

./app.js :

var express = require('express');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var app = express();


// Extras para Socket.io
// var server = require('http').Server(app);
// var io = require('socket.io')(server);

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

app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(require('less-middleware')(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));

// Requests

app.get('/', function (req, res) {
    res.render('index', { title: 'Express' });
});

// Socket requests
//
//io.on('connection', function (socket) {
//    socket.emit('news', { hello: 'world' });
//    socket.on('my other event', function (data) {
//        console.log(data);
//    });
//});

/// catch 404 and forward to error handler
app.use(function(req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
});

/// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
    app.use(function(err, req, res, next) {
        res.status(err.status || 500);
        res.render('error', {
            message: err.message,
            error: err
        });
    });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
        message: err.message,
        error: {}
    });
});

module.exports = app;

var server = require('http').createServer(app);
server.listen(app.get('port'), function(){
    console.log('Express listening on port ' + app.get('port'));
});

var io = require('socket.io').listen(server);

io.sockets.on('connection', function (socket) {
    socket.emit('news', { hello: 'world' });
    socket.on('my other event', function (data) {
        console.log(data);
    });
});
Ali Shakiba
  • 20,549
  • 18
  • 61
  • 88
Maxinne
  • 1,693
  • 2
  • 23
  • 47

2 Answers2

16

I fiddled more with my files, and got it to work, here is how I got it to work:

./bin/www : Need to keep the require app.js, or it won't work.

#!/usr/bin/env node
//var debug = require('debug')('generated-express-app');
var app = require('../app');

//app.set('port', process.env.PORT || 3000);
//
//var server = app.listen(app.get('port'), function() {
//  debug('Express server listening on port ' + server.address().port);
//});
//
//var io = require('socket.io').listen(server);
//
//io.sockets.on('connection', function (socket) {
//    socket.emit('news', { hello: 'world' });
//    socket.on('my other event', function (data) {
//        console.log(data);
//    });
//});

./app.js : All that was on www goes here, before the last export.

var express = require('express');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var app = express();


// Extras para Socket.io
// var server = require('http').Server(app);
// var io = require('socket.io')(server);

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

app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(require('less-middleware')(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));

// Requests

app.get('/', function (req, res) {
    res.render('index', { title: 'Express' });
});

// Socket requests
//
//io.on('connection', function (socket) {
//    socket.emit('news', { hello: 'world' });
//    socket.on('my other event', function (data) {
//        console.log(data);
//    });
//});

/// catch 404 and forward to error handler
app.use(function(req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
});

/// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
    app.use(function(err, req, res, next) {
        res.status(err.status || 500);
        res.render('error', {
            message: err.message,
            error: err
        });
    });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
        message: err.message,
        error: {}
    });
});

var debug = require('debug')('generated-express-app');
//var app = require('../app');

app.set('port', process.env.PORT || 3000);

var server = app.listen(app.get('port'), function() {
    debug('Express server listening on port ' + server.address().port);
});

var io = require('socket.io').listen(server);

io.sockets.on('connection', function (socket) {
    socket.emit('news', { hello: 'world' });
    socket.on('my other event', function (data) {
        console.log(data);
    });
});

module.exports = app;

I used the express generator to gen the project, disabled the routes, as it seems that Socket.io won't support express routes.

Ali Shakiba
  • 20,549
  • 18
  • 61
  • 88
Maxinne
  • 1,693
  • 2
  • 23
  • 47
  • 2
    Thanks - found this after hours of searching and it fixed my issue. Straight out of the box for express 4, this is the only way to get socket.io 1.1 work. – user1480926 Sep 28 '14 at 17:49
  • 1
    Thanks a lot, I also was spending hours figuring out what was wrong. It was the /bin/www folder all along. – Jorre Oct 10 '14 at 13:23
  • I use angular as templating, so I don't need any server templating language. Is there a way to disable jade and use pure html? – Akxe Feb 10 '15 at 10:53
  • @Akxe, tried http://stackoverflow.com/questions/7520541/node-js-express-without-using-jade – Maxinne Feb 10 '15 at 14:41
  • Why can't we pass app to socket io, for example? var io = require('socket.io').listen(app) – Adam Mendoza Feb 18 '15 at 11:46
  • @AdamMendoza I think these links can lead you to a productive answer: http://expressjs.com/api.html#app.listen and http://socket.io/docs/server-api/#server#attach%28port:number,-opts:object%29:server Basically ´app´ is the main express itself, meanwhile app.listen is only a convenience function to call some Node JS functions at once. – Maxinne Feb 18 '15 at 15:26
2

So, one year later, and more node studies later, I found that the previous answer is quite incomplete, and may lead to sub-optimal usage of express. This is the more correct approach to use Node + Express + Socket.io without problems:

On /bin/www.js, replace var http = require('http'); with var server = require('http').Server(app);, and remove var server = http.createServer(app);

And that's it... Use your routes normally, place chats anywhere, no problems anymore.

Note: I left the old response unedited to preserve comments and such relevant and on context.

Maxinne
  • 1,693
  • 2
  • 23
  • 47
  • Could you please elaborate more on this answer? After doing these changes what else would yo do? Where are you finally adding the *socket.io* routes? – adelriosantiago Feb 07 '17 at 18:48
  • Socket don't use routes... It connects via events on the main loop. Tomorrow I will do a simple example and add it to the response, ok? – Maxinne Feb 08 '17 at 03:26
  • 1
    Hey, @joaoBeno can you please give an example? – Sssssuppp Dec 05 '20 at 04:11