【问题标题】:Nodejs/Socket - Add/Remove User From RoomNodejs/Socket - 从房间添加/删除用户
【发布时间】:2016-01-06 17:14:05
【问题描述】:

我在将用户添加到房间列表时遇到问题,我可以设法在全局级别(每个连接的用户)做到这一点,但是在房间的基础上添加和删除用户,我似乎无法掌握。

我添加了一个名为

的新变量

房间用户

app.js

var express = require('express')
  , app = express()
  , http = require('http')
  , server = http.createServer(app)
  , io = require('socket.io').listen(server);

server.listen(8080);

// routing
app.get('/', function (req, res) {
  res.sendfile(__dirname + '/index.html');
});

// usernames which are currently connected to the chat
var usernames = {};

// usernames which are currently connected to the chat
var roomUsers = {};

// rooms which are currently available in chat
var rooms = ['room1','room2','room3'];

io.sockets.on('connection', function (socket) {
    
    // when the client emits 'adduser', this listens and executes
    socket.on('adduser', function(username){
        // store the username in the socket session for this client
        socket.username = username;
        // store the room name in the socket session for this client
        socket.room = 'room1';
        // add the client's username to the global list
        usernames[username] = username;
        // send client to room 1
        socket.join('room1');
        // echo to client they've connected
        socket.emit('updatechat', 'SERVER', 'you have connected to room1');
        // echo to room 1 that a person has connected to their room
        socket.broadcast.to('room1').emit('updatechat', 'SERVER', username + ' has connected to this room');
        socket.emit('updaterooms', rooms, 'room1');
        // update the list of users in chat,client side
        io.sockets.emit('updateUsers', usernames);
        //
        //io.sockets.in(socket.room).emit('updateUsers', usernames);
    });
    
    // when the client emits 'sendchat', this listens and executes
    socket.on('sendchat', function (data) {
        // we tell the client to execute 'updatechat' with 2 parameters
        io.sockets.in(socket.room).emit('updatechat', socket.username, data);
    });
    
    socket.on('switchRoom', function(newroom){
        socket.leave(socket.room);
        socket.join(newroom);
        socket.emit('updatechat', 'SERVER', 'you have connected to '+ newroom);
        // sent message to OLD room
        socket.broadcast.to(socket.room).emit('updatechat', 'SERVER', socket.username+' has left this room');
        delete usernames[socket.username];
        // update socket session room title
        socket.room = newroom;
        socket.broadcast.to(newroom).emit('updatechat', 'SERVER', socket.username+' has joined this room');
        socket.emit('updaterooms', rooms, newroom);
        io.sockets.emit('updateUsers', usernames);

    });
    

    // when the user disconnects.. perform this
    socket.on('disconnect', function(){
        // remove the username from global usernames list
        delete usernames[socket.username];
        // update list of users in chat, client-side
        io.sockets.emit('updateUsers', usernames);
        // echo globally that this client has left
        socket.broadcast.emit('updatechat', 'SERVER', socket.username + ' has disconnected');
        socket.leave(socket.room);
    });
});

对于 io.sockets.emit('updateUsers', usernames); 哪里出错有什么建议吗?并删除用户名[socket.username]; (显然我需要将其更改为 roomUsers)

前端.js

var socket = io.connect('http://localhost:8080');

    // on connection to server, ask for user's name with an anonymous callback
    socket.on('connect', function(){
        // call the server-side function 'adduser' and send one parameter (value of prompt)
        socket.emit('adduser', prompt("What's your name?"));
    });

    // listener, whenever the server emits 'updatechat', this updates the chat body
    socket.on('updatechat', function (username, data) {
        $('#conversation').append('<b>'+username + '></b> ' + data + '<br>');
    });

    // listener, whenever the server emits 'updateusers', this updates the username list
  socket.on('updateUsers', function(data) {
    $('#users').empty();
    $.each(data, function(key, value) {
      $('#users').append('<div>' + key + '</div>');
    });
  });



    // listener, whenever the server emits 'updaterooms', this updates the room the client is in
    socket.on('updaterooms', function(rooms, current_room) {
        $('#rooms').empty();
        $.each(rooms, function(key, value) {
            if(value == current_room){
                $('#rooms').append('<div>' + value + '</div>');
            }
            else {
                $('#rooms').append('<div><a href="#" onclick="switchRoom(\''+value+'\')">' + value + '</a></div>');
            }
        });
    });

    function switchRoom(room){
        socket.emit('switchRoom', room);
    }
    
    // on load of page
    $(function(){
        // when the client clicks SEND
        $('#datasend').click( function() {
            var message = $('#data').val();
            $('#data').val('');
            // tell server to execute 'sendchat' and send along one parameter
            socket.emit('sendchat', message);
        });

        // when the client hits ENTER on their keyboard
        $('#data').keypress(function(e) {
            if(e.which == 13) {
                $(this).blur();
                $('#datasend').focus().click();
            }
        });
    });

index.html

<script src="/socket.io/socket.io.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script src="http://localhost:8888/chat/js/frontend.js"></script>
<div style="float:left;width:100px;border-right:1px solid black;height:300px;padding:10px;overflow:scroll-y;">
    <b>ROOMS</b>
    <div id="rooms"></div>
</div>
<div style="float:left;width:100px;border-right:1px solid black;height:300px;padding:10px;overflow:scroll-y;">
  <b>USERS</b>
  <div id="users"></div>
</div>
<div style="float:left;width:300px;height:250px;overflow:scroll-y;padding:10px;">
    <div id="conversation"></div>
    <input id="data" style="width:200px;" />
    <input type="button" id="datasend" value="send" />
</div>

【问题讨论】:

  • 套接字可以连接多个房间。当套接字断开连接时,它会自动离开所有房间,因此您无需在disconnect 中指定socket.leave()
  • 你为什么要删除switchRoom中的用户名?
  • 因为它有 3 个房间,所以我想要它,所以如果你在 room1,然后你点击 room2,它会从 room1 中删除用户名,然后添加到 room2
  • 如何为用户名指定房间?你在写:usernames[username] = username;。也许您希望 usernames 成为一个数组?
  • 那么你希望用户名看起来像:var usernames = { room1: [], room2: [], room3: [] }; 你应该添加一个用户名,比如:usernames[roomName].push(username); 并在updateUsers 发射中发送usernames[roomName]。在switchRooms 中,在添加用户名之前,您应该将其从之前的房间中删除,例如:var userIndex = usernames[oldRoom].indexOf(username); if (userIndex !== -1) { usernames[oldRoom].splice(userIndex, 1); } else { throw "username doesn't exist in old room."; }。不要忘记删除disconnect 中的用户名。另外不要忘记更新您的客户端。

标签: javascript html node.js sockets


【解决方案1】:

您应该在 utils 文件夹下的 users.js 中定义添加/删除函数,然后将其导入 app.js。

users.js

let users = [];

const addUser = ({ id, username, room }) => {
  // Clean the data
  username = username.trim().toLowerCase();
  room = room.trim().toLowerCase();

  // always validate the data
  if (!username || !room) {
    return {
      error: "Username and room are required!"
    };
  }

  // Check for existing user
  const userExist = users.find(user => {
    return user.room === room && user.username === username;
  });

  // Validate username
  if (userExist) {
    return {
      error: "Username is in use!"
    };
  }

  // Store user
  const user = { id, username, room };
  users.push(user);
  return { user };
};

const removeUser = id => {
  const index = users.findIndex(user => {
    user.id === id;
  });
  if (index !== 1) {
  //splice method returns the removed the user
    return users.splice(index, 1);
  }
};
module.exports = { addUser, removeUser};

用户在提交登录表单并加入房间时被添加。我们需要 removedUser 来发送特定房间中的断开连接的用户。

app.js

const { addUser, removeUser} = require("./utils/users");
//a simple utility function that send text and date
const { sendMessage } = require("./utils/messages");

io.on("connection", socket => {
  //once user submitted the form, server receives the username and room info. data={username,room}
  socket.on("join", (data, callback) => {
  //if you check addUser function it either returns error or user
    const { error, user } = addUser({ id: socket.id, ...data });

    if (error) {
      return callback(error);
    }
    //if there is no error, user joins the room
    socket.join(user.room);
    //send this generated message to the connected users
    socket.emit("message", sendMessage("Admin", "Welcome!"));
    //user broadcast to send info all users in the room but the last joined
    socket.broadcast
      .to(user.room)
      .emit(
        "message",
        sendMessage("Admin", `${user.username} has joined!`)
      );

    callback();
  });

socket.on("disconnect", () => {
    //socket.id is generated by socket upon connection
    const user = removeUser(socket.id);
    if (user) {
      io.to(user.room).emit(
        "message",
        sendMessage("Admin", `${user.name} has left`)
      );
    }
  });

/utils/messages.js

const generateMessage = function(username, text) {
  return {
    username,
    text,
    created: new Date().getTime()
  };
};
module.exports = { generateMessage };

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-03
    • 1970-01-01
    • 2018-09-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-03
    相关资源
    最近更新 更多