如何在 Expressjs 和 Socket.io 上连接同一端口

wri*_*per 3 javascript node.js express socket.io

我使用 Express.js 和 Socket.io 来开发聊天应用程序。

第一次我使用 Express-Generator 创建项目并从节点 ./bin/www 脚本开始,但是,我删除了所有 ./bin/www 文件并与 app.js 合并

我在生产模式中使用 HTTPS,在开发模式中使用 HTTP。

所以我写了这样的代码。

[应用程序.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}`);
  });
Run Code Online (Sandbox Code Playgroud)

当我运行应用程序时,它向我显示这样的错误。

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
Run Code Online (Sandbox Code Playgroud)

错误消息说它应该附加服务器实例,所以我多次修改我的代码 .createServer 行,但它不起作用。

但是当我使用另一个端口(例如 3000)时,它工作正常。但我想使用相同的端口。

我将套接字 Io 代码放在同一个 app.js 中。

这是socketio代码的一部分。

/* 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);
    })
  })

Run Code Online (Sandbox Code Playgroud)

[正面代码]

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

我该如何解决这个问题?

ant*_*ant 10

正如您的问题中显示的错误消息中所述,socket.io 需要一个http.Server.

您需要做的是调用app.listen以获取 的实例http.Server,然后将其传递给 socket.io,例如:

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)
Run Code Online (Sandbox Code Playgroud)