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

使用NetInfo检测用户在线/离线状态异常问题排查

问题诊断与修复方案

核心问题分析

  1. 初始在线状态判断逻辑错误
    代码中初始设置用户在线状态时,用socket.id === user.socketId判断,这只会把当前客户端自己标记为在线,其他用户的isOnline永远为false,完全不符合需求。

  2. NetInfo逻辑破坏用户在线状态
    网络状态监听中调用updateAllIsOnline,会把所有用户的在线状态统一设置为当前设备的网络连接状态,混淆了设备网络状态和用户在线状态,属于严重逻辑错误。

  3. 缺少socket身份注册
    客户端连接socket后,未向服务器发送用户身份信息,导致服务器无法识别当前用户,也无法推送正确的在线用户列表。

  4. 初始用户列表获取时机问题
    获取用户列表时socket可能还未完全建立连接,导致依赖socket.connected的判断失效。

修复后的完整代码

import { View, Text, FlatList, StyleSheet, StatusBar, TouchableOpacity } from 'react-native';
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import io from 'socket.io-client';

const SOCKET_URL = 'http://10.100.102.23:3002';

export default function MentorsChat() {
    const [selectedId, setSelectedId] = useState(null);
    const [users, setUsers] = useState([]);
    const [socket, setSocket] = useState(null);

    useEffect(() => {
        // 创建socket连接
        const socketInstance = io(SOCKET_URL);
        setSocket(socketInstance);

        // 连接成功后,向服务器发送用户身份(替换为当前登录用户真实ID)
        socketInstance.on('connect', () => {
            const currentUserId = '当前登录用户ID';
            socketInstance.emit('register', currentUserId);

            // 连接稳定后获取用户列表
            axios.get('http://10.100.102.23:3002/api/users')
                .then(response => {
                    setUsers(response.data);
                })
                .catch(error => {
                    console.log(error);
                });

            // 监听服务器推送的在线用户列表
            socketInstance.on('onlineUsers', (onlineUserIds) => {
                setUsers(prevUsers => prevUsers.map(user => ({
                    ...user,
                    isOnline: onlineUserIds.includes(user._id)
                })));
            });
        });

        // 监听单个用户上线事件
        socketInstance.on('online', userId => {
            setUsers(prevState => prevState.map(user => 
                user._id === userId ? { ...user, isOnline: true } : user
            ));
        });

        // 监听单个用户下线事件
        socketInstance.on('offline', userId => {
            setUsers(prevState => prevState.map(user => 
                user._id === userId ? { ...user, isOnline: false } : user
            ));
        });

        // 组件卸载时关闭连接
        return () => {
            socketInstance.close();
        };
    }, []);

    const renderItem = ({ item }) => {
        const backgroundColor = item._id === selectedId ? "#6e3b6e" : "#f9c2ff";

        return (
            <TouchableOpacity onPress={() => setSelectedId(item._id)} style={[styles.item, { backgroundColor }]}>
                <Text style={styles.title}>{item.fullName}</Text>
                <Text style={styles.subtitle}>{item.isMentor ? "Mentor" : "Not a mentor"}</Text>
                <Text style={styles.subtitle}>{item.isOnline ? "Online" : "Offline"}</Text>
            </TouchableOpacity>
        );
    };

    return (
        <View style={styles.container}>
            <FlatList
                data={users}
                renderItem={renderItem}
                keyExtractor={(item) => item._id}
                extraData={selectedId}
            />
        </View>
    );
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        marginTop: StatusBar.currentHeight || 0,
    },
    item: {
        backgroundColor: '#f9c2ff',
        padding: 20,
        marginVertical: 8,
        marginHorizontal: 16,
    },
    title: {
        fontSize: 32,
    },
    subtitle: {
        fontSize: 16,
        marginTop: 4,
        color: '#666',
    },
});

服务器端配套要求

  • 维护在线用户ID列表,通过register事件记录用户ID与socket的映射关系。
  • 客户端连接后,主动推送当前所有在线用户ID列表(触发onlineUsers事件)。
  • 用户断开连接时,向其他客户端广播offline事件。

内容的提问来源于stack exchange,提问作者armory victory

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 20:34:56