Using socket.io in Express 4 and express-generator's /bin/www

Here is how you can add Socket.io to a newly generated Express-Generator application:

  1. Create a file that will contain your socket.io logic, for example socketapi.js:

socketapi.js:

const io = require( "socket.io" )();
const socketapi = {
    io: io
};

// Add your socket.io logic here!
io.on( "connection", function( socket ) {
    console.log( "A user connected" );
});
// end of socket.io logic

module.exports = socketapi;
  1. Modify your bin/www launcher. There are two steps: requiring your Socket.io api and attaching the HTTP server to your socket.io instance right after creating the HTTP server:

bin/www:

/**
 * Module dependencies.
 */

var app = require('../app');
var debug = require('debug')('socketexpress:server');
var http = require('http');
let socketapi = require("../socketapi"); // <== Add this line

/**
 * Get port from environment and store in Express.
 */

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

/**
 * Create HTTP server.
 */

var server = http.createServer(app);
socketapi.io.attach(server); // <== Also add this line

(...)
  1. Then you just need to add the Socket.io client in your index.html. Add the following just before the </body> closing tag:

index.html

    (...)
    <script src="/socket.io/socket.io.js"></script>
    <script>
        var socket = io();
    </script>
</body>
</html>
  1. Finally you can start your Express server:
  • Unix based: DEBUG=myapp:* npm start
  • Windows: set DEBUG=myapp:* & npm start

Note 1

If for any reason you need access to your socket api in your app.js, then you could instead import your socket api in app.js, and re-export it:

app.js

var express = require('express');
var socketapi = require("./socketapi"); // <== Add this line
(...)
// You can now access socket.io through the socketapi.io object
(...)
module.exports = { app, socketapi }; // <== Export your app and re-export your socket API here

Then in your bin/www launcher, instead of importing your socket api on its own line, just import it along your app:

bin/www

var {app, socketapi} = require('../app'); // <== Import your app and socket api like this
(...)
var server = http.createServer(app);
socketapi.io.attach(server); // <== You still have to attach your HTTP server to your socket.io instance

Note 2 This answer was updated to work with the latest Express Generator (4.16 at time of writing) and latest Socket.io (3.0.5 at time of writing).


A little different approach to initiate socket.io, it groups all related code in one place:

bin/www

/**
 * Socket.io
 */
var socketApi = require('../socketApi');
var io = socketApi.io;
io.attach(server);

socketApi.js

var socket_io = require('socket.io');
var io = socket_io();
var socketApi = {};

socketApi.io = io;

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

socketApi.sendNotification = function() {
    io.sockets.emit('hello', {msg: 'Hello World!'});
}

module.exports = socketApi;

app.js

// Nothing here

In this way all socket.io related code in one module and function from it I can invoke from anywhere in application.


It turns out it really was some basic sintax problem.... I got these lines from this socket.io chat tutorial...

on ./bin/www, just after var server = app.listen(.....)

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

so now I create the ../sockets/base.js file and put this little fellow inside it:

module.exports = function (io) { // io stuff here... io.on('conection..... }

Yeah! Now it works... So i guess i really had no option other than starting socket.io inside /bin/www , because that is where my http server was started. The goal is that now i can build socket functionality in other file(s), keeping the thing modular, by require('fileHere')(io);

<3