writingdeveloper
writingdeveloper

Reputation: 1076

How can I connect same port on Expressjs and Socket.io

I use Express.js & Socket.io to develop chat app.

At first time I create my project with Express-Generator and starts with node ./bin/www script but, I remove all the ./bin/www file and combine with app.js

I use HTTPS in production Mode and use HTTP with development Mode.

So I write a code like this.

[app.js]

require('dotenv').config()
const express = require('express');
const path = require('path');
const fs = require('fs')
const app = express();
let io = require('socket.io')(app)   // I Attach (app) here!!

const https = require('https')
const http = require('http')
const PORT = process.env.PORT || 443;
const domain = 'example.com';
const option = process.env.NODE_ENV === "production" ? {
    ca: fs.readFileSync('/etc/letsencrypt/live/' + domain + '/fullchain.pem'),
    key: fs.readFileSync(path.resolve(process.cwd(), '/etc/letsencrypt/live/' + domain + '/privkey.pem'), 'utf8').toString(),
    cert: fs.readFileSync(path.resolve(process.cwd(), '/etc/letsencrypt/live/' + domain + '/cert.pem'), 'utf8').toString(),
  } :
  undefined;

// In Production Mode use HTTPS Server
// In Development Mode use HTTP Server

/* HTTPS Server */
option
  ?
  https.createServer(option, app).listen(PORT, () => {
    console.log(`Server is running at port ${PORT}`);
  }) :
  undefined;
/* HTTP Server */
option
  ?
  http
  .createServer(function (req, res) {
    res.writeHead(301, {
      Location: "https://" + req.headers["host"] + req.url
    });
    res.end();
  })
  .listen(80) :
  http.createServer(app).listen(PORT, () => {
    console.log(`Server is running at port ${PORT}`);
  });

And when I run app it shows me an error like this.

Users\super\Downloads\project\build\node_modules\socket.io\lib\index.js:258
    throw new Error(msg);
    ^

Error: You are trying to attach socket.io to an express request handler function. Please pass a http.Server instance.
    at Server.listen.Server.attach (C:\Users\super\Downloads\project\build\node_modules\socket.io\lib\index.js:258:11)
    at new Server (C:\Users\super\Downloads\project\build\node_modules\socket.io\lib\index.js:59:17)
    at Server (C:\Users\super\Downloads\project\build\node_modules\socket.io\lib\index.js:44:41)
    at Object.<anonymous> (C:\Users\super\Downloads\project\build\app.js:13:30)
    at Module._compile (internal/modules/cjs/loader.js:1156:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1176:10)
    at Module.load (internal/modules/cjs/loader.js:1000:32)
    at Function.Module._load (internal/modules/cjs/loader.js:899:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12)
    at internal/main/run_main_module.js:18:47
Program node app.js exited with code 1

Error message said that it should be attach server instance, So I modify my code .createServer line several time but It won't work.

But When I use use another port (ex 3000) it works fine. But I want to use same port.

And I put the socket Io code in same app.js.

This is a part of socketio code.

/* Socket IO Functions */
io.on('connection', function (socket) {
  // Join Room Scoket
  socket.on('JoinRoom', function (data) {
    socket.leave(`${data.leave}`)
    // console.log(`Leave ROOM : ${data.leave}`)
    socket.join(`${data.joinedRoomName}`);
    // console.log(`NEW JOIN IN ${data.joinedRoomName}`)
    // console.log(`RECEIVER : ${data.receiver}`)
    // When Reads the message SET notice to '1'
    // db.query(`UPDATE chatData SET notice='1' WHERE chatReceiver=? AND roomName=?`, [data.receiver, data.joinedRoomName])

    Chat.aggregate([{
        $match: {
          'chatReceiver': data.receiver,
          'roomName': data.joinedRoomName,
          'chatNotice': 1
        }
      },
      {
        $set: {
          'chatNotice': 0
        }
      }
    ], (err, result) => {
      if (err) throw err;
      // console.log(result);
    })
  })

[Front Side Code]

/* Global */
let socket = io.connect('http://127.0.0.1:3000'); // But I want to use 80 or 443 port 

How can I solve this?

Upvotes: 3

Views: 3128

Answers (1)

ant
ant

Reputation: 1278

As described in the error message shown in your question, socket.io requires an instance of http.Server.

What you need to do is call app.listen to get an instance of http.Server, and then pass that to socket.io, eg:

var PORT = process.env.PORT || 3000
var app = express()
var server = app.listen(PORT, function() {
    console.log('server listening at', server.address())
})
var io = require('socket.io')(server)

Upvotes: 10

Related Questions