How do I get the http.server from the express app?

23,430

Solution 1

As far as I know, the Express app object does not know the server object. The way things work in Express, the app object is given to the server object, not the other way around. In fact a single app object can even be used with more than one server (sometimes done for an http and https server).

You can get access to the server object from within a request handler with req.connection.server, but that comes from the server as part of the context with a request, that's not something the app object itself knows.

So, if you want access to the server object for use with socket.io at initialization time, you will have to capture the server object into a variable where it is created.

The code you show in your question does not create or start a server. The usual two ways to start a server for use with Express are this:

var express = require('express');
var app = express();
// Express creates a server for you and starts it
var server = app.listen(80);

Or, you create the server yourself and pass express to it as the handler:

var express = require('express');
var app = express();
// you explicitly create the http server
var server = require('http').createServer(app);
server.listen(80);

In each of these cases, you end up with the server object in a variable and can then use that with socket.io.


You can get access to the server from inside an Express route handler within the processing of a request from either the req or res object that are passed to a request handler.

res.connection.server
req.connection.server

Solution 2

The server is returned when you call app.listen(). For example:

const server = app.listen(process.env.NODE_PORT, () => {
  console.log('Listening', server.address());
});

Solution 3

You can write a simple wrapper to either instantiate or get the Socket IO instance in your Express app, by putting the following in some file:

//Dependencies
const socketIo = require('socket.io');

//Placeholder for instance
let io;

//Export handler to instantiate or get instance
module.exports = function(server) {
  if (server) {
    io = socketIo(server);
  }
  return io;
};

Then, you can instantiate this instance the usual way when setting up Express:

const app = require('express')();
const server = require('http').Server(app);
const io = require('./path-to-your-file')(server);

And when you need it later in your routes or code elsewhere, you can get it as follows:

const io = require('./path-to-your-file')();

This is of course a simplified example, but you can modify the logic to suit your needs.

Solution 4

You can also use the following code to accomplish the same thing.

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

server.listen(80);

For more information, I sugges that you refer to this link

Solution 5

I had this problem when I used wepack devServer with socket-io and jfriend00's comment helped me. I use this trick:

let server;
app.use((req, res, next) => {
    if (!server){
        server = req.connection.server;
        //do fancy staffs with http-server
    }
    next();
})
Share:
23,430
Graeme Perrow
Author by

Graeme Perrow

I am a software developer working for SAP in Waterloo, Ontario. I am a member of the SAP HANA Cockpit engineering team. For twenty years, I was a member of the SAP SQL Anywhere engineering team. I write primarily in Javascript, C, C++, python, and perl. In my spare time, I enjoy sports, primarily lacrosse, baseball, and hockey.

Updated on October 04, 2020

Comments

  • Graeme Perrow
    Graeme Perrow over 3 years

    I am writing a server-side node.js application that uses express to handle HTTP requests and I'm adding websockets (socket.io) support. However I don't have access to the code that starts the HTTP server. I am writing an express router and functions to handle various URLs. My code looks like:

    var express = require('express');
    var router = express.Router();
    router.post( myURL, myFunction );
    

    When setting up the router I want to use socket.io to listen for websocket connections as well. I cannot pass express or express() into require('socket.io')( xxx ), I need to pass the http.Server object. But since I didn't start the server, how can I get it?