Nodejs / Socket - 从房间添加/删除用户

时间:2015-10-08 22:01:42

标签: node.js sockets

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

我添加了一个名为

的新变量
  

roomUsers

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)

frontend.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>

1 个答案:

答案 0 :(得分:0)

您应该在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};

当用户提交登录表单并加入会议室时,将添加用户。我们需要removeUser来发送处于特定房间的断开连接的用户。

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 };