React应用中函数内socket.emit()无法生效求助
Socket.io 客户端 sendMessageHandler 中 emit 无效问题
Socket后端运行正常,已通过Postman验证。问题在于socket.emit在useEffect中可以正常工作,但在sendMessageHandler函数内无法生效。通过日志排查发现,socket.emit("send-message", message)语句前后的日志均正常输出,但该语句似乎未执行。
服务端代码
import { Server } from "socket.io"; import { server } from "./app"; import dotenv from "dotenv"; import { Message } from "./types/message.types"; import deleteUserFromSocketList from "./utils/lib/deleteUserFromSocketList"; dotenv.config(); const io = new Server(server, { cors: { origin: process.env.CLIENT_URL, methods: ["GET", "POST"], credentials: true, }, }); interface User { name: string; email: string; uid: string; sid: string; } var connectedUsers: User[] = []; io.use((socket, next) => { //TODO verify user request //TODO save or replace user socket id to database next(); }); io.on("connection", (socket) => { io.to(socket.id).emit("user-sid", { sid: socket.id }) socket.on("user-details", (user) => { connectedUsers = deleteUserFromSocketList(connectedUsers, user); connectedUsers.push(user); console.log(`user joined: ${socket.id}`); io.emit("user-joined", connectedUsers); }); socket.on("send-message", (msg) => { // if (msg.receipient.sid.length === 0) return; socket.to(msg.receipient.sid).emit("receive-message", msg); console.log(msg); console.log("message delivered"); }); socket.on("disconnect-user", () => { const updatedUserList: User[] = []; connectedUsers.forEach((user) => { if (user.sid !== socket.id) updatedUserList.push(user); }); connectedUsers = updatedUserList // socket.disconnect() io.emit("user-left", connectedUsers); }); }); export { io };
客户端代码
import { useEffect, useState } from "react"; import { getCookie } from "../../utils"; import UsersList from "./userBar"; import CommunicationPanel from "./chatPanel"; import { Message } from "../../types/Message.types"; import { getAllCookies } from "../../utils/getCookie"; import { User } from "../../types/User.types"; import createMessage from "../../utils/createMessage"; import { io } from "socket.io-client"; const URL = process.env.REACT_APP_API_URL || ""; const socket = io(URL, { withCredentials: true, retries: 5, reconnectionDelay: 5000, reconnectionAttempts: 3, autoConnect: true }); export default function Dashboard() { const [isInitial, setInitial] = useState<boolean>(true); const [currSid, setCurrSid] = useState<string>(""); const [activeChat, setActiveChat] = useState<User | null>(null); const [messageList, setMessageList] = useState<Message[]>([]); const [onlineUsers, setOnlineUsers] = useState<User[]>([]); if (getCookie("isUserLoggedIn") !== "true") { window.location.replace("/"); } useEffect(() => { function notifyUserConnected() { socket.on("user-sid", (connData) => { const sid: string = connData.sid; setCurrSid(sid); const { name, email, uid } = getAllCookies(); const user = { name, email, uid, sid }; socket.emit("user-details", user); }); } function updateUserList(userList: User[]) { setOnlineUsers(userList); } function updateMessageList(msg: Message) { setMessageList((list) => { return [...list, msg]; }); } socket.on("connect", notifyUserConnected); socket.on("user-joined", (list) => updateUserList(list)); socket.on("user-left", (list) => updateUserList(list)); socket.on("receive-message", (msg) => updateMessageList(msg)); return () => { socket.off("user-joined"); socket.off("user-left"); socket.off("user-sid"); socket.off("receive-message"); socket.emit("disconnect-user"); }; }, []); const sendMessageHandler = (msg: string) => { const message: Message = createMessage(msg, activeChat, currSid); socket.connect() socket.emit("send-message", message); }; return ( <div className="md:flex justify-center items-start w-[100%] h-[85vh] overflow-hidden"> <UsersList users={onlineUsers.filter((user) => user.sid !== currSid)} setActiveChat={(args: User) => { setActiveChat(args); setInitial(false); }} /> {currSid} <CommunicationPanel messageList={messageList} sendMessageHandler={sendMessageHandler} chatData={activeChat} isInitial={isInitial} /> </div> ); }
排查与解决建议
移除重复的
socket.connect()调用:客户端初始化时已设置autoConnect: true,组件挂载后socket已建立连接,sendMessageHandler中重复调用connect()会导致连接状态异常,阻塞emit操作。修改后代码:const sendMessageHandler = (msg: string) => { const message: Message = createMessage(msg, activeChat, currSid); socket.emit("send-message", message); };添加参数有效性校验:确保
sendMessageHandler执行时activeChat不为null、currSid不为空,避免生成无效消息对象:const sendMessageHandler = (msg: string) => { if (!activeChat || !currSid) return; const message: Message = createMessage(msg, activeChat, currSid); socket.emit("send-message", message); };监听socket错误事件:在
useEffect中添加错误监听,排查连接或emit时的异常:useEffect(() => { // ... 原有代码 function handleSocketError(error) { console.error("Socket错误:", error); } socket.on("error", handleSocketError); return () => { // ... 原有清理代码 socket.off("error", handleSocketError); }; }, []);检查服务端消息转发逻辑:取消服务端
send-message事件中if (msg.receipient.sid.length === 0) return;的注释,排查是否因接收方sid无效导致消息未转发。确认socket连接状态:在
sendMessageHandler中打印连接状态,验证emit时socket是否处于连接状态:const sendMessageHandler = (msg: string) => { console.log("Socket连接状态:", socket.connected); if (!activeChat || !currSid) return; const message: Message = createMessage(msg, activeChat, currSid); socket.emit("send-message", message); };
内容的提问来源于stack exchange,提问作者Piyush
相关产品推荐
相关产品推荐

