Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vue.js/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js Socket.IO显示房间的已连接用户列表_Node.js_Vue.js_Socket.io - Fatal编程技术网

Node.js Socket.IO显示房间的已连接用户列表

Node.js Socket.IO显示房间的已连接用户列表,node.js,vue.js,socket.io,Node.js,Vue.js,Socket.io,我有一个vue.js/node/socket.io聊天应用程序。我需要创建一个在线用户列表,当用户连接或断开连接时,该列表将保持最新状态。我正在尝试使用此代码,但当有人加入房间时,我无法更新用户列表。我怎样才能解决这个问题 'use strict'; const express = require('express'); const socketIO = require('socket.io'); const PORT = process.env.PORT || 3000; const IN

我有一个vue.js/node/socket.io聊天应用程序。我需要创建一个在线用户列表,当用户连接或断开连接时,该列表将保持最新状态。我正在尝试使用此代码,但当有人加入房间时,我无法更新用户列表。我怎样才能解决这个问题

'use strict';

const express = require('express');
const socketIO = require('socket.io');

const PORT = process.env.PORT || 3000;
const INDEX = '/index.html';

// TODO: controllo query url
const server = express()
.use('/modules', express.static(__dirname + '/node_modules'))
.use('/assets', express.static(__dirname + '/assets'))
.use((req, res) => res.sendFile(INDEX, { root: __dirname }))
.listen(PORT, () => console.log(`Listening on ${PORT}`));
const io = socketIO(server);

let connectedUsers = [];

io.on('connection', (socket) => { 
  console.log('Connected peer: '+ socket.id);
  socket.on('accessRoom', (username,room) => {
    connectedUsers = { nickname: username, id: socket.id } 
    socket.join(room, (err) => {
      socket.emit('accessStatus', 'done');
      console.log(this)
    })
    updateUsersList()
  })

  socket.emit('channelStatus', socketData)
  socket.emit('message', socket.id, 'connected')

  socket.on('message', (id, msg) => { 
    socket.broadcast.emit('message', id, msg);
  })

  socket.on('disconnect', () => {
    console.log('Disconnected')
  })

  function updateUsersList(){
    socket.emit('usersList', connectedUsers)
  }

});

io.on('ping', (socket) => {
  console.log(socket);
  io.emit('pong');
});
vuejs代码

export default {
  data () {
    return {
      isRegistered: false,
      isConnected: false,
      user: '',
      message: '',
      id: '',
      channel: '',
      usersList: []
    }
  },
  mounted() {
    this.pingServer()
    this.updateUsersList()
    io.on('pong', (data) => {
      console.log(data);
    })
    io.on('channelStatus', (data) => {
        if( data.status === 'connected' ){
          this.id = data.IHMnumber;
          this.isConnected = true;
          console.log(data);
        }
    })
    io.on('message', (from, msg) => {
      console.log(from)
      console.log(msg)
    })
  },
  methods: {
    pingServer(){
      io.emit('ping')
    },
    connect(){
      if( this.isRegistered === false){
        this.user = this.user;
        this.isRegistered = true;
        console.log(this.isRegistered);
        console.log(this.user);
        io.open()
        return this.user;
      }
    },
    updateUsersList(){
      io.on('usersList', (users) => {
        console.log(users);
        this.usersList.push(users);
      })
    },
    sendMessage(){
      console.log(this.message)
      io.emit('message', this.id ,this.message)
    }
  }
}

使用此代码,创建文件室的用户将不会收到用户列表。对于将加入会议室的用户,在控制台中,我可以看到他们已添加到用户阵列中,但如果有人加入会议室,事件将不会以更新的信息登录控制台。也许我需要重构代码,也许我在错误的地方调用了updateUsersList?

首先,如果按房间划分用户,请向他们的房间发送消息。在这里,我向您展示解决问题的一种方法。将“connectedUsers”的类型更改为map,其中键为房间名称、值-用户数组:

const connectedUsers = new Map();
要处理用户列表的更改,请为join创建方法

joinToRoom(room, user) {
    // create users array, if key not exists
    if (!connectedUsers.has(room)) {
        connectedUsers.set(room, []);
    }
    // add user to room array
    connectedUsers.get(room).push(user);
    // call update function
    updateUsersList(room);
}
离开房间:

leaveRoom(room, user) {
    let userList = connectedUsers.get(room);
    // delete user
    userList = userList.filter(u => u !== user);
    // update user list
    if (!userList.length) {
        // delete key if no more users in room
        connectedUsers.delete(room);
    } else
    {
        connectedUsers.set(room, userList);
        // call update function
        updateUsersList(room);
    }
}
同时更改方法updateUsersList:

function updateUsersList(room){
    socket.to(room).emit('usersList', {
        room: room,
        users: connectedUsers.get(room)
    });
}
请注意,我们向事件“usersList”发出一个对象,其中包含房间字段,用于澄清您应该在前端更新的房间

最后一步是调用我们的方法:

当用户加入聊天室时:

socket.join(room, (err) => {
  const user = resolve user from request;
  socket.emit('accessStatus', 'done');
  joinToRoom(room, user);
  console.log(this);
})
当用户离开房间时: 我看不到leaveRoomroom的活动,所以你只要打电话给leaveRoomroom,用户


此外,您还应该创建一些映射来比较socketId和user,以正确处理断开连接事件并调用leaveRoomroom,user方法。

首先,如果按房间划分用户,请将消息发送到他们的房间。在这里,我向您展示解决问题的一种方法。将“connectedUsers”的类型更改为map,其中键为房间名称、值-用户数组:

const connectedUsers = new Map();
要处理用户列表的更改,请为join创建方法

joinToRoom(room, user) {
    // create users array, if key not exists
    if (!connectedUsers.has(room)) {
        connectedUsers.set(room, []);
    }
    // add user to room array
    connectedUsers.get(room).push(user);
    // call update function
    updateUsersList(room);
}
离开房间:

leaveRoom(room, user) {
    let userList = connectedUsers.get(room);
    // delete user
    userList = userList.filter(u => u !== user);
    // update user list
    if (!userList.length) {
        // delete key if no more users in room
        connectedUsers.delete(room);
    } else
    {
        connectedUsers.set(room, userList);
        // call update function
        updateUsersList(room);
    }
}
同时更改方法updateUsersList:

function updateUsersList(room){
    socket.to(room).emit('usersList', {
        room: room,
        users: connectedUsers.get(room)
    });
}
请注意,我们向事件“usersList”发出一个对象,其中包含房间字段,用于澄清您应该在前端更新的房间

最后一步是调用我们的方法:

当用户加入聊天室时:

socket.join(room, (err) => {
  const user = resolve user from request;
  socket.emit('accessStatus', 'done');
  joinToRoom(room, user);
  console.log(this);
})
当用户离开房间时: 我看不到leaveRoomroom的活动,所以你只要打电话给leaveRoomroom,用户


您还应该创建一些映射来比较socketId和user,以正确处理断开连接事件并调用leaveRoomroom,user方法。

我需要尝试测试您的代码,我现在正在尝试使用io.sockets,它似乎将引用所有套接字连接。。这将使我能够向同一房间内连接的客户端发送新的连接更新,但我不确定该事件是否也针对其他房间触发,而不是您建议的leaveRoom功能的预期行为,是否有任何特定的代码可以应用于从用户数组中删除断开连接的客户端?我认为doc中的示例非常适合您,您只需添加,您可以映射rooms变量并在leaveRoom函数中调用我正在测试您建议的代码,但在节点中,我收到一个错误,行const user=resolve user from request;有什么修复吗?节点服务器将不会运行,我得到一个语法错误:意外的标识。这里有一个注释,您可以实现您的逻辑来解析用户。我不知道你的授权策略,所以我不能给你具体的例子。它必须类似于1从请求2获取令牌如果是jwt解析令牌3在db 4中查找用户数据将用户数据设置为const userI我需要尝试并测试代码,我现在正在尝试使用io.sockets,它似乎将引用所有套接字连接。。这将使我能够向同一房间内连接的客户端发送新的连接更新,但我不确定该事件是否也针对其他房间触发,而不是您建议的leaveRoom功能的预期行为,是否有任何特定的代码可以应用于从用户数组中删除断开连接的客户端?我认为doc中的示例非常适合您,您只需添加,您可以映射rooms变量并在leaveRoom函数中调用我正在测试您建议的代码,但在节点中,我收到一个错误,行const user=resolve user from request;有什么修复吗?节点服务器将不会运行,我得到一个语法错误:意外的标识。这里有一个注释,您可以实现您的逻辑来解析用户。我不知道你的授权策略,所以我不能给你具体的例子。在jwt解析令牌3在db 4中查找用户数据将用户数据设置为const user的情况下,它必须类似于1从请求2获取令牌