当前位置: 首页 > 知识库问答 >
问题:

Socket.io-反应:如何显示房间中连接的用户?

澹台举
2023-03-14

我正在尝试映射连接到我的聊天应用程序的用户,并在div中呈现他们。

我将用户保存在一个对象数组中,并在用户在后端连接和断开与聊天室的连接时发送一个事件更新该数组,在前端获取该对象,将其保存在一个数组中,并使用map显示用户。

当我映射数组来显示用户时,我的页面只显示当前用户和后续用户,而不显示之前连接的用户。例如,如果我打开名为“布鲁斯”的应用程序和另一个用户为“安德鲁”的页面,第一个页面将同时显示用户和第二个仅显示“安德鲁”。如果我console.log从后端得到的数组,它会显示两个用户。如果我退出任何页面或重新加载它,它会显示“TypeError:无法读取未定义的属性‘用户名’”

后端

const users = []

    // Storing user
    const user = { id, username, room } 
    users.push(user)

const getUsersInRoom = (room) => {
    return users.filter((user) => user.room === room)
}

socket.on('join', ({ username, room }, callback) => {
    io.to(user.room).emit('roomData', {
      room: user.room,
      users: getUsersInRoom(user.room)
    })
    callback()
  })

  socket.on('disconnect', () => {
      io.to(user.room).emit('roomData', {
        room: user.room,
        users: getUsersInRoom(user.room)
      })
    }
  })

前端

    const [usersName, setUsersName] = useState([]);

    useEffect(() => {
        socket.on('roomData', ({room, users}) => {
            setUsersName(previousUsersName => [...previousUsersName, users]);
        })
    },[]);

    return (
             <div>
                {
                    usersName.map((name, i) => (
                        <div key={i}>
                            <p>
                                <span>{name[i].username}</span>
                            </p>
                        </div>
                    ))
                }
              <div/>

当I console.log(usersName)时,它以以下格式显示数组

[Array(1)]
   0: Array(1)
      0:
         id: "yXXo7TXVHWN1bzl6AAAV"
         room: "Games"
         username: "Bruce"

我相信后端是正确的,因为我得到了所有用户。我认为的问题是我如何映射数组使用"name[i]. username",因为当我重新加载页面,它打破了它,页面呈现的名称不正确,如上所述。

任何帮助都很感激,如果它令人困惑或我丢失了一些数据,请让我知道。

共有1个答案

欧阳哲
2023-03-14

这是我使用name[i]. username在地图中显示名称的方式。

我猜是因为索引正在更新和破坏应用程序,当新用户进入页面时,它不会显示前辈,因为索引正在指向新用户。

我通过映射包含我在后端接收到的对象数组的第一个数组,并映射对象数组本身以显示名称,使其工作。

我在我的状态下保存数组的方式也是错误的。由于我正在接收所有已连接的用户,因此无需使用以前的用户填充阵列,然后添加新用户。

这里是变化

    const [usersName, setUsersName] = useState([]);

        socket.on('roomData', ({room, users}) => {
            setUsersName([users]);
        })


        {
            usersName.map((name,index) => 
                <div key={index}>
                    {
                        name.map((username, subindex) =>
                            <p key={subindex}>{username.username}</p>
                        )
                    }
                </div>
            )
        }
 类似资料:
  • 问题内容: 我正在尝试使用laravel开发实时聊天应用程序。我遇到了问题。当我运行“ node index.js”时,在命令提示符下连续显示“连接已建立”消息。 我的index.js文件是: 我的index.html页面是: 我该如何解决? 问题答案: 客户端不断尝试一遍又一遍地进行连接的通常原因是,因为客户端和服务器版本的socket.io不匹配,导致它们不兼容。您没有显示如何在网页中加载so

  • 问题内容: 这是我使用socket.io作为WebSocket并使用pub / sub redis后端的代码。 每个新的io请求都将创建新的Redis连接。如果有人打开带有100个选项卡的浏览器,则Redis客户端将打开100个连接。看起来不太好。 如果Cookie相同,是否可以重用Redis连接?因此,如果有人打开许多浏览器选项卡,也将其视为打开1连接。 问题答案: 实际上,如果要在“连接”事件

  • 问题内容: 我想请你帮忙。我在socket.io的客户端上遇到了麻烦,我想在客户端调用此代码以在socket.io中创建一个房间: 我不知道这是否正确,如果不正确,请帮助我纠正这些家伙。我不是在节点js和套接字方面专业,但我已经阅读了他们的wiki。有没有可能创造空间的方法? 问题答案: 不需要创建Socket.IO中的房间,而是在套接字加入时创建一个房间。它们是在服务器端加入的,因此您必须指示服

  • 我试图从apache反向代理后面连接到socket.io服务器。我在端口8888上运行apache。nodejs服务器运行在同一台机器的端口9096上。为了进行测试,在我的本地计算机上配置代理,如下所示: 在客户端代码中,我执行如下操作: 如何使它连接到本地主机:8888/some/path/socket.io/1?123983759 ?

  • 问题内容: io.sockets.on(‘connection’, function(socket) { socket.object = socket.id; 怎么做? 问题答案: 请注意,此功能在高于1.0的socket.io版本中不再可用,建议保留您的socket.id数组,以便您可以在需要时对其进行迭代。 您可以使用以下功能实现此目的: