Javascript – Using socket.io in Express 4 and express-generator’s /bin/www

expressjavascriptnode.jssocket.io

So here is the deal: I'm trying to use socket.io in an express project. After Express Js 4 was lauched, i've updated my express-generator and now the app initial functions goes into ./bin/www file, including those vars (www file contents: http://jsfiddle.net/avMa5/ )

var server = app.listen(app.get('port'), function() {..}

(check it by npm install -g express-generator and then express myApp

that being said, let's remember how socket.io docs ask us to fire it:

var app = require('express').createServer();
var io = require('socket.io')(app);

Ok but i can't do it inside app.js, like recommended. This should be done in ./bin/www in order to work. in ./bin/www this is what i can do to get it working:

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

Ok this works, but i can't use the io var anywhere else, and i really don't want to put my socket.io functions on www file.

I guess this is just basic syntax, but I can't get this to work, not even using module.exports = server or server.exports = server nor module.exports.io = app(io) on www file

So the question is: how can i use socket.io having this /bin/www file as starting point of my app?

Best Answer

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).

Related Topic