Socket.io 在服务器刷新/关闭时保持连接

Socket.io keep connection up when server get refreshed / turned down

假设我是套接字的新手,我正在尝试在服务器(节点 w/Express)上设置第一个配置。

这样做时,我遇到了一个问题,即每次保存时 nodemon 都会崩溃,返回 Error: listen EADDRINUSE: address already in use :::8080

这里是服务器实现:

import express from "express";
import cors from "cors";
import { Server, Socket } from "socket.io";
import { createServer } from "http";
import morgan from "morgan";

// App configuration
const app = express();
const server = createServer(app);
const io = new Server(server);
const port = process.env.PORT || 8080;

// Middlewares
app.use(cors());
app.use(express.json());
app.use(morgan("combined"));

// Socket connection
io.on("connect", (socket: Socket) => {
  socket.send("test");
});

server.listen(port, () => {
  console.log(`Server is up and running on ${process.env.NODE_ENV} - port ${port}`);
});

我认为这是因为 socket.io 连接永远不会关闭/断开连接,让服务器实例处于监听状态。

我环顾四周,发现许多 q/a 建议使用命令来查找和终止进程,但我需要一个能够在每次 express 服务器关闭时自动断开套接字的解决方案.

我尝试了以下方法:

io.on("disconnect", () => {
  io.sockets.disconnect();
}

如建议的那样 ,但 TS 抱怨 io.sockets.disconnect() 有一个 Property 'disconnect' does not exist on type 'Namespace<DefaultEventsMap, DefaultEventsMap>'.ts(2339)

知道应该如何解决这个问题吗?

我认为套接字 io 初始化可能存在问题。你能试试 https://socket.io/get-started/chat#Integrating-Socket-IO:

中显示的这种类型的初始化吗
const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const io = require('socket.io')(server);

app.get('/', (req, res) => {
  res.sendFile(__dirname + '/index.html');
});

io.on('connection', (socket) => {
  console.log('a user connected');
});

server.listen(3000, () => {
  console.log('listening on *:3000');
});

所以基本上像这样将服务器对象从套接字 io 传递到默认导入(现在,您在 socket.io 中使用“服务器”):

import express from "express";
import cors from "cors";
import ioDefault, { Server, Socket } from "socket.io";
import { createServer } from "http";
import morgan from "morgan";

// App configuration
const app = express();
const server = createServer(app);
const io = ioDefault(server);
const port = process.env.PORT || 8080;

// Middlewares
app.use(cors());
app.use(express.json());
app.use(morgan("combined"));
// ...

更新:

问题出在同一端口上的另一台服务器 运行。要检查哪个进程在特定端口上 运行ning,您可以 运行

netstat -anpe | grep "8080" | grep "LISTEN"

如果在基于 debian 的系统(ubuntu、fedora 和其他)中未安装 netstat 运行 sudo apt install net-tools

然后你可以用它的 pid 杀死它:

kill -9 5454