【问题标题】:Socket.io - Know in which room socket isSocket.io - 知道哪个房间的插座是
【发布时间】:2016-08-03 11:43:46
【问题描述】:

我正在使用 node.js 服务器在 socket.io 上编写一个简单的聊天。所以我需要知道在哪个房间插座。例如,socket 已经连接并加入了一个房间。因此,当此套接字发送消息时,我只想将其广播到该房间中的套接字(sck.broadcast.to(it_room).emit)。

io.on("connection", function(sck) {
  ...
  sck.join(availableRoom);
  sck.on("message", function(msg) {
    sck.broadcast.to(**its room**).emit(msg);
    sck.emit(msg);
  });
  ...
});

我不需要一组套接字和有关它们的信息(在哪个房间等)。

【问题讨论】:

    标签: javascript node.js sockets websocket socket.io


    【解决方案1】:

    您首先输入您的用户名和您加入的聊天室。提交表单后,用户名和房间信息将作为查询字符串附加 URL。在浏览器中: location.search :这是我们访问查询字符串的方式。我们必须解析它。

    将此 CDN 添加到您的 main.html

    <script src="https://cdnjs.cloudflare.com/ajax/libs/qs/6.6.0/qs.min.js"></script>
    

    此 CDN 用于 npm querystringify 包。因为在客户端设置 npm 包会很头疼,所以 cdn 更容易处理。确保在小时 html 中的其他 js 文件之前首先加载 cdn 脚本文件。加载此 CDN 后,我们可以使用:

    const { username, room } = Qs.parse(location.search, { ignoreQueryPrefix: true })
    

    { ignoreQueryPrefix: true } 此选项将省略“?”来自查询字符串。

    一旦您获得用户名和房间名称,我们就可以从客户端发出我们的事件。

    client.js

    socket.emit('join', { username, room }, (error) => {
        if (error) {
            alert(error)
            location.href = '/' //will keep the client in the same url
        }
    })
    

    现在我们必须从服务器端监听这个事件。但我们必须跟踪用户。

    index.js

    io.on("connection", socket => {
    
      socket.on("join", ({ username, room }, callback) => {
        //we have to define addUser function
    
    
    let users = [];
    
    const addUser = ({ id, username, room }) => {
      // Clean the data
      username = username.trim().toLowerCase();
      room = room.trim().toLowerCase();
    
      // Validate the data
      if (!username || !room) {
        return {
          error: "Username and room are required!"
        };
      }
    
      // Check for existing user
      const existingUser = users.find(user => {
        return user.room === room && user.username === username;
      });
    
      // Validate username
      if (existingUser) {
        return {
          error: "Username is in use!"
        };
      }
    
      // Store user
      const user = { id, username, room };
      users.push(user);
      // users=users.push(user) this will cause error
      return { user };
    };
    //as you see this function will return either error or user object
    
    //Socket generates an id upon connection.
    //result is either error or user
        const { error, user } = addUser({ id: socket.id, username, room });
    
        if (error) {
          return callback(error);
        }
    
        socket.join(user.room);//socket joined to this room
        //now time to emit a new event
        socket.emit("message", ( "Welcome!"));
        socket.broadcast
          .to(user.room)
          .emit(
            "message",
            (`${user.username} has joined!`)
          );
    
    
    //broadcast will send messages to everyone in the chat room except the connected socket
    
        callback(); //success scenario. let the client knows that it is allowed to connect
      })   
    })
    

    【讨论】:

      【解决方案2】:

      尝试以下方法,但我不确定它是否适用于所有情况。

      Object.keys(sck.manager.roomClients[sck.id])[1]
      

      我通过记录套接字找到了这个,然后我查找了房间信息并按照您在我的代码中看到的方式提取了它。


      我使用的是 0.9.6 socket.io 版本,可能最新版本有不同的解决方案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-01-04
        • 1970-01-01
        • 2011-12-03
        • 2018-09-26
        • 2013-05-01
        • 2018-07-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多