多个侦听器和 removeListener 删除所有内容 Socket.io
Posted
技术标签:
【中文标题】多个侦听器和 removeListener 删除所有内容 Socket.io【英文标题】:Multiple listeners & removeListener removes everything Socket.io 【发布时间】:2021-09-20 11:58:20 【问题描述】:伙计们!我正在写一个 socket.io 聊天。当用户发送消息时,会发生 socket.on 事件。一切正常,但听众的数量呈指数级增长。我尝试使用 socket.off/socket.remove... 删除侦听器,将事件 socket.on 与连接分开 - 没有任何效果。拜托,请帮我弄清楚。我正在使用 react、node、socket 和 mongoDB
服务器部分:
const express = require("express");
const app = express();
const cors = require("cors");
const UserModel = require("./models");
app.use(cors());
app.use(express.json());
app.use(express.urlencoded( extended: true ));
app.options("http://localhost:3000", cors());
const mongoose = require("mongoose");
require("dotenv").config();
const http = require("http").createServer(app);
const io = require("socket.io")(http,
cors:
origin: ["http://localhost:3002"],
,
);
http.listen(3001, function ()
console.log("Server is running");
);
io.on("connection", (socket) =>
console.log("Socket connected", socket.id);
socket.on("message:send", (data) =>
console.log("Пришло в socket.onMessage", data);
socket.emit("message:fromServer", data);
// socket.removeListener("message:fromServer");
);
);
const userApi = require("./api/userApi");
app.use("/", userApi);
app.use((err, _, res, __) =>
return res.status(500).json(
status: "fail",
code: 500,
message: err.message,
);
);
const PORT, DB_HOST = process.env;
const dbConnection = mongoose.connect(DB_HOST,
useNewUrlParser: true,
useFindAndModify: false,
useCreateIndex: true,
useUnifiedTopology: true,
);
dbConnection
.then(() =>
console.log("DB connect");
app.listen(PORT || 3000, () =>
console.log("server running");
);
)
.catch((err) =>
console.log(err);
);
客户端部分: io.js
import io from "socket.io-client";
export const socket = io("http://localhost:3001/");
消息组件
import React from "react";
import useState from "react";
// import useSelector from "react-redux";
// import getMessages from "../../Redux/selectors";
import socket from "../helpers/io";
import Message from "../Message/Message";
import nanoid from "nanoid";
export default function MessageFlow()
const [message, setMessage] = useState([]);
socket.on("message:fromServer", (data) =>
console.log("На фронт пришло сообщение: ", data);
setMessage([...message, data]);
// setMessage((message) => [...message, data]);
console.log("Массив сообщений компонента MessageFlow", message);
console.log(socket.io.engine.transports);
// socket.off();
// getEventListeners(socket)['testComplete'][0].remove()
// socket.removeListener("message:fromServer");
);
// const dispatch = useDispatch();
// const allMessages = useSelector(getMessages);
return (
<div id="mainDiv">
message &&
message.map((i) =>
// return <Message />;
return <Message content=i.userId id=nanoid() />;
)
</div>
);
消息表单 - 发送过程的开始
import React, useState from "react";
import useDispatch, useSelector from "react-redux";
import sendMessage from "../../Redux/Chat/Chat-operations";
import getUser from "../../Redux/selectors";
import getToken from "../../Redux/Auth/Auth-selectors";
import socket from "../helpers/io";
import useEffect from "react";
import styles from "./MessageForm.module.css";
export default function MessageForm()
const [message, setMessage] = useState("");
const dispatch = useDispatch();
const userId = useSelector(getUser);
const currentToken = useSelector(getToken);
// const getAll = useSelector(allContacts);
const updateMessage = (evt) =>
setMessage(evt.target.value);
;
const handleSubmit = (e) =>
e.preventDefault();
if (message)
socket.emit("message:send", userId: message );
dispatch(
sendMessage(
_id: userId,
text: message,
,
currentToken
)
);
else
alert(`Молчать будем?`);
;
return (
<div className=styles.messageInputContainer>
<form>
<input
type="text"
value=message
onChange=updateMessage
required
className=styles.messageInput
placeholder="Type message to send"
/>
<button
type="submit"
className=styles.messageAddBtn
onClick=handleSubmit
>
Send
</button>
</form>
</div>
);
【问题讨论】:
【参考方案1】:你在每次渲染时添加一个监听器,你应该使用 useEffect 钩子
export default function MessageFlow()
useEffect(()=> // triggered on component mount or when dependency array change
const callback = (data) =>
// what you want to do
socket.on("message:fromServer", callback);
return () => // on unmount, clean your listeners
socket.removeListener('message:fromServer', callback);
, []) // dependency array : list variables used in your listener
// [...]
【讨论】:
以上是关于多个侦听器和 removeListener 删除所有内容 Socket.io的主要内容,如果未能解决你的问题,请参考以下文章
如何避免ConcurrentModificationException听一次监听器的情况
DragSortListView-Android Studio 无法识别 dropListener 和 removeListener