【问题标题】:When pushing user to array, multiple Array's being created将用户推送到数组时,会创建多个数组
【发布时间】:2018-12-02 23:41:09
【问题描述】:

我正在创建一个应用程序(聊天应用程序)并将每个用户名推送到一个数组。使用 socket.io,每当我调用事件将用户名推送到客户端数组时,都会创建数组的多个实例。

例如,我登录的第一个用户很好,然后当添加另一个用户时,数组会加倍,然后是三倍等等。提前感谢您的帮助。我正在执行此操作的发出事件位于 USERS_CONNECTED 事件中。

我也很抱歉下面的代码太草率了。

服务器

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

const publicPath = path.join(__dirname, 'public');
const port = process.env.PORT || 3001;
let app = express();
let server = http.createServer(app);
var io = socketIO(server);
let username;
app.use(express.static(publicPath));
let usersOnline = []; //keeps track of current users online

io.on('connection', (socket) => {
let user = socket.id;
socket.emit('user', user);

    socket.id = "anon";

    socket.on('new user', function(data,callback) {
        //if user name is taken
        if(usersOnline.indexOf(data) != -1 || data == ''){
            callback(false);
        }else{
            //if username is not taken
            callback(true);
            socket.id = data;
            username = data;
            //pushes data(username) to data
            usersOnline.push(socket.id);
            //sends back to client usersOnline array
            io.sockets.emit('USERS_CONNECTED', {usersOnline: usersOnline, user: socket.id});
            console.log(usersOnline.length)
        }
    });
    socket.on('disconnect', () => {
        usersOnline.splice(usersOnline.indexOf(socket.id), 1);
        //emits count users, sets current user
        io.sockets.emit('USERS_CONNECTED', {usersOnline: usersOnline, user: socket.id});
        console.log(usersOnline.length)

    });


    socket.on('send msg' , function(data){

        io.sockets.emit('send msg', {msg: data, user: socket.id});
    })



});

server.listen(port, () => {
    console.log('server is running master')
});

客户

let socket = io();
let input = document.querySelector('#input_username');
let form = document.querySelector('form')

let userName_page = document.querySelector(".userName_page");
let chat_page = document.querySelector(".chat_page");
let chatWrapper = document.querySelector(".chat_wrapper")
let counter = document.getElementById("counter");
let users = document.querySelector(".users_online")
let join_btn = document.querySelector(".button-effect")
let msg_input = document.querySelector("#sendMsg");
let btn_send = document.querySelector("#send_btn");
let onlineUsers = [];
let sent_ = document.querySelector(".sent_");
let receive_ = document.querySelector(".receive_");
let newUser_text = document.querySelector(".welcome_box")
let user;
let isTyping = document.querySelector('#isTyping')
let welcome_header = document.querySelector("#welcome_header");

let users_online_container = document.querySelector(".users_online");


join_btn.addEventListener("click", function(e){
    e.preventDefault();
    user = input.value;
    //sets user name to input.value
    socket.emit('new user', input.value, function(data){
        if(data){
            userName_page.style.display = "none"
            chat_page.style.display = "flex";
            welcome_header.innerHTML = input.value + ' has joined the party';
            addAnimation();
        }else{
            if(input.value == ''){
                input.classList.add("input_error");
                let error_msg = document.getElementById('error_input');
                error_msg.innerHTML = '*Invalid, Please Type a Username'
                error_msg.style.display = "block";
                input.style.border = "2px solid #d9534f";

            }else{
                input.classList.add("input_error");
                let error_msg = document.getElementById('error_input');
                error_msg.style.display = "block";
                error_msg.style.border = "2px solid #d9534f"
                error_msg.innerHTML = "Woops, sorry but that user name is already taken, please try again";
            }

        }
    });

    //sets up new user

    socket.on('USERS_CONNECTED' , function (data){

        //counts online users currently
        counter.innerHTML = (data.usersOnline.length + " Online");
        for(let i = 0; i < data.usersOnline.length; i++){
            onlineUsers.push(data.usersOnline);
            let h = document.createElement("h3");
            fish.appendChild(h);
        }
        console.log(onlineUsers)
    });


});

//msg send

btn_send.addEventListener('click', function(){
    socket.emit('send msg', msg_input.value);

});
//checks if enter is pressed, if so emits message to chat
function search(ele) {
    if(event.key === 'Enter') {
        socket.emit('send msg', msg_input.value);
    }
}
//send message events

socket.on('send msg', function(data){
    if(data.user == user){
        //sender logic
            msg_input.value = '';
            let p = document.createElement('p');
            receive_.append(p);
            p.innerHTML = "<span class = 'er'>" + 'You' + "</span>" + ": " + data.msg;
            p.style.textAlign = 'right';
            p.style.backgroundColor = "#5cb85c";
            p.style.justifyContent = "flex-end";
            p.style.paddingRight = "2em";
        }
        else{
            //receiver logic
            msg_input.value = '';
            let p = document.createElement('p');
            receive_.append(p);
            p.innerHTML = "<span class = 'er'>" + data.user + "</span>" + ": " + data.msg;
            p.style.textAlign = 'left';
            p.style.backgroundColor = "#5bc0de";
            p.style.paddingLeft = "2em";
        };

        //makes sure scroll stays at bottom
        receive_.scrollTop = receive_.scrollHeight;
    });
function addAnimation(){
    newUser_text.classList.add("act");
}

$( document ).ready(function(){
    let header = document.querySelector(".feedback");

    var timeout;

    function timeoutFunction() {
        typing = false;
        socket.emit("typing", false);
    }

    $('#sendMsg').keyup(function() {
        typing = true;
        socket.emit('typing', 'typing...');
        clearTimeout(timeout);
        timeout = setTimeout(timeoutFunction, 5000);
    });

    socket.on('typing', function(data) {
        if (data) {
            $('#isTyping').html(data);
            $('#isTyping').classList.add('act')
        } else {
            $('#isTyping').html("");
        }
    });

})

【问题讨论】:

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


    【解决方案1】:

    您应该在客户端替换整个数组而不是推送。只需堆栈跟踪您的代码:

    首先在服务器端连接时,您将新用户 ID 推送到 usersOnline 数组并通过 usersOnline 属性中的 USERS_CONNECTED 事件在对象中发出该数组。客户端接收该对象并将用户对象(不完全是一个新用户)推送到onlineUsers 数组。所以例如。 1 个用户连接到服务器,usersOnline 数组将是:

    [ 'user1' ]
    

    然后第二个用户连接到服务器:

    [ 'user1', 'user2' ]
    

    并且该数组正在发送给 user2,即USERS_CONNECTED 事件发送的整个对象将是:

    { usersOnline: [ 'user1', 'user2' ], user: 'user2' }
    

    现在在客户端而不是替换你正在推送整个新数组,所以[ 'user1', 'user2' ] 你得到[ [ 'user1', 'user2' ] ]

    【讨论】:

    • 太棒了,这很有意义。你如何建议我更换阵列? onlineUsers.replace(data.usersOnline) ?
    • 好吧,我建议您最好将用户列表单独发送到新连接的客户端并将新用户广播给其他在线人员,这样推送才真正有意义。但是如果你想这样做,你可以将新数组分配给以前的变量,即onlineUsers = data.usersOnline。当然,如果您没有对先前数组对象的直接引用。如果您仅通过数组的键引用它们,它应该可以工作
    • 啊,好吧,我想出了 onlineUsers.splice(0, onlineUsers.length, ...data.usersOnline) 来创建新的数组实例。谢谢大家的帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-10
    • 2013-01-21
    • 1970-01-01
    • 1970-01-01
    • 2016-03-23
    • 1970-01-01
    相关资源
    最近更新 更多