You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Socket.io服务端消息推送异常:客户端收不到好友请求

问题分析与修复方案

1. 事件参数不匹配(核心问题)

客户端触发sendFriendRequest事件时,仅传递了接收者邮箱一个参数,但服务端的事件监听器期望接收recipientEmail(接收者)和senderEmail(发送者)两个参数。这会导致服务端的senderEmail变量为undefined,最终发送给接收方的是无效值,同时存在参数传递逻辑的误解。

修复方式(二选一即可)

方案一:客户端补充发送者参数

修改addFriend函数,传递接收者邮箱+当前用户(发送者)的邮箱:

const addFriend = (potentialFriend) => {
    socket.emit("sendFriendRequest", potentialFriend, auth.email);
};

方案二:服务端从握手信息取发送者(更安全)

直接从当前连接的socket握手信息中获取发送者邮箱,避免客户端传递伪造信息:

socket.on('sendFriendRequest', (recipientEmail) => {
    const senderEmail = socket.handshake.query.email;
    const recipientSocket = userSockets.get(recipientEmail);

    if (recipientSocket) {
        console.log("sending to friend req to", recipientEmail)
        recipientSocket.emit('receiveFriendRequest', senderEmail);
    }
});

2. Socket实例重复创建导致监听失效

组件每次渲染都会新建socket实例,但useEffect依赖为空数组,仅在组件首次挂载时绑定旧socket的事件监听,后续新建的socket未绑定receiveFriendRequest监听器,导致无法接收事件。

修复方式:用useRef保存Socket实例

import io from 'socket.io-client';
import { useRef, useEffect, useContext } from 'react';

const FriendOpts = ({ user2Email, locationState = null, component = null }) => {
    const auth = useContext(AuthContext);
    // 用useRef持久化socket实例
    const socketRef = useRef(null);

    useEffect(() => {
        socketRef.current = io("http://localhost:8000/friends", {
            query: {
                email: auth.email
            },
        });

        const socket = socketRef.current;

        socket.on('connect', () => {
            console.log(`Connected to the friends namespace`);
        });

        socket.on('receiveFriendRequest', (senderEmail) => {
            console.log(senderEmail)
        });

        // 组件卸载时断开连接
        return () => {
            socket.disconnect();
        };
    }, [auth.email]); // 用户切换时重新连接

    const addFriend = (potentialFriend) => {
        socketRef.current.emit("sendFriendRequest", potentialFriend);
    };

    // ... 其他组件逻辑
};

3. 可选优化:处理用户断开连接

当前服务端的userSockets Map不会在用户断开时移除无效socket,可能导致后续请求使用失效连接。添加断开处理:

friendsNamespace.on('connection', (socket) => {
    const email = socket.handshake.query.email;
    console.log(email, "joined")
    userSockets.set(email, socket);

    socket.on('disconnect', () => {
        userSockets.delete(email);
        console.log(email, "disconnected");
    });

    // ... 其他逻辑
});

内容的提问来源于stack exchange,提问作者Isfar Oshir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 13:02:37