40

I'm trying to hook socket.io and express.js together:

var socket = require('./socket_chat/socket.js');

var express = require('express'),
    app = module.exports.app = express();

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

    app.use(express.static(__dirname + '/app'));

io.sockets.on('connection', socket);

At the line: var io = require('socket.io').listen(app); I'm getting an error:

Error: You are trying to attach socket.io to an expressrequest handler function. Please pass a http.Server instance.

There doesn't seem to be anything on SO/google about this error...

alyx
  • 2,593
  • 6
  • 39
  • 64

5 Answers5

72

You should use http module:

var http = require('http');
var express = require('express'),
    app = module.exports.app = express();

var server = http.createServer(app);
var io = require('socket.io').listen(server);  //pass a http.Server instance
server.listen(80);  //listen on port 80

//now you can use app and io

More details you can find in a documentation: http://socket.io/docs/#using-with-express-3/4

Oleg
  • 22,300
  • 9
  • 68
  • 84
  • 1
    You the man! you saved my day. I just have to use the server.listen() instead of app.listen() – Jimmy Ilenloa Dec 18 '14 at 12:37
  • 19
    But what is the reason that we cannot use the express() instead we have to use the http module? what is the alternative to express' createServer()? – Umer Hassan Jul 31 '16 at 06:21
  • 1
    http.createServer(app) may be depreciated https://stackoverflow.com/questions/13499010/nodejs-express-launching-my-app-express-createserver-is-deprecated use @Tagada 's answer – Dr Deo Apr 06 '20 at 04:34
59

You can do it without using http module

app.listen return a server instance you can use for socket.io

const express = require('express');
const app = express();
const server = app.listen(port, () => {
    console.log("Listening on port: " + port);
});
const io = require('socket.io')(server);
Tagada
  • 836
  • 10
  • 14
3

For socket.io to work with express, you need a server instance and therefore attach it to socket.io

I'll use .listen method of express since it returns an http.Server object. Read the docs here

const port = 3000,
      app = require('express')(),
      io = require('socket.io')();

// Your normal express routes go here...

// Launching app
const serverInstance = app.listen(port, () => {
    console.log('App running at http://localhost:' + port);
});

// Initializing socket.io
io.attach(serverInstance);
Patrissol Kenfack
  • 764
  • 1
  • 8
  • 22
1

http method works for me. I tried this.

import express from 'express'
import http from 'http'

import { Server } from 'socket.io'
const app = express()

const server = http.createServer(app)
const io = new Server(server)
server.listen(3001)
Ganesh MB
  • 1,109
  • 2
  • 14
  • 27
0

enter image description hereAfter a lot of searching i found a way similar to you guys:

//declare your app as
const app = express()

//declare a connection separately from app as
const server = http.createServer(app)

//finally declare io from server instead of app
const io = socketio(server)

//to use io inside route screens, set io inside req as
(req,res,next)=>{
  req.io=io
}

then use app as you wish

i got this answer from this amazing site: https://towardsdatascience.com/building-a-real-time-web-app-in-nodejs-express-with-socket-io-library-d9b50aded6e6

Naruto Uzumaki
  • 442
  • 4
  • 7