【问题标题】:Node sends data back multiple times everytime a user adds new data每次用户添加新数据时,节点都会多次发回数据
【发布时间】:2015-11-02 05:46:07
【问题描述】:

首先,我要为这个措辞可怕的标题道歉;在过去的 20 分钟里,我一直在想一个问题,但我不知道用一种简洁的方式来描述我遇到的问题。如果有人有更好的建议,请告诉我或编辑标题。

背景:为了学习 NodeJS,我正在创建一个聊天服务器。当用户点击createRoomBtn 时,会创建一个包含用户刚刚创建的房间名称的事件,并发送到app.js 中的socket.js 模块,app.js 然后将房间附加到房间数组(这些房间在浏览器中显示为列表),并向所有用户(包括活动用户)创建广播事件。

问题:假设有一个空列表,用户添加了一个名为“NodeJS”的新房间,这将在屏幕上显示房间,一切都很好。现在,如果我要添加另一个房间,例如 Socket.io,浏览器会呈现以下结果:Socket.io, NodeJS, NodeJS。如果我要添加“Javascript”,结果将是Javascript, Socket.io, NodeJS, Socket.io, Node.JS。基本上,浏览器一遍又一遍地渲染列表,每次列表缩小一个。我不知道为什么会这样。奇怪的是,如果我按刷新,浏览器会正确呈现列表Javascript, Socket.io, NodeJS。怎么回事?

socket.js

module.exports = function(io, rooms) {
    var chatrooms = io.of('/roomlist').on('connection', function(socket) {  //io.of creates a namespace 
        console.log('Connection established on the server');
        socket.emit('roomupdate', JSON.stringify(rooms));   


        socket.on('newroom', function(data) {
            console.log(data);
            rooms.push(data);
            socket.broadcast.emit('roomupdate', JSON.stringify(rooms)); 
            socket.emit('roomupdate', JSON.stringify(rooms));   

        })      
    })

    var messages = io.of('/messages').on('connection', function(socket) {   
        console.log('Connected to the chatroom!');

        socket.on('joinroom', function(data) {
            socket.username = data.user; 
            socket.userpic = data.userPic;
            socket.join(data.room);         
        })

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

            socket.broadcast.to(data.room_number).emit('messagefeed', JSON.stringify(data));  
        })
    })
} 

chatrooms.html:

<!doctype html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title>{{title}}</title>
        <link rel="stylesheet" href="../css/chatrooms.css">
        <script src="//code.jquery.com/jquery-1.11.0.min.js"> </script> 
        <script src="/socket.io/socket.io.js"> </script> 
        <script>
        $(function() {
            var host = '{{config.host}}';       
            var socket = io.connect(host + '/roomlist');

            socket.on('connect', function() {
                console.log('connection established');      
            })  
            socket.on('roomupdate', function(data) {
                $('.roomlist').html('');

                var procData = JSON.parse(data); 

                for (var i = 0; i < procData.length; i++) { 
                    var str = '<a href="room/' + procData[i].room_number + '"><li>'
                    + procData[i].room_name + '<li></a>'; 
                    $('.roomlist').prepend(str);

                    console.log(str);

                }
            }) 

            $(document).on('click', '#createRoomBtn', function() {
                var room_name = $('#newRoomText').val();
                console.log(room_name);
                if (room_name != '') {
                    var room_number = parseInt(Math.random() * 10000);
                    socket.emit('newroom', {room_name: room_name, room_number: room_number});
                    $('#newRoomText').val('');                  
                }
            }) 
        }) 

        </script>
    </head>  

<body>

    <div class="cr-userbox">
        <img src="{{user.profilePic}}" class="userPic">
        <h3 class="username">{{user.fullName}}| <a href="/logout">Logout</a></h3>
    </div>


    <div class="cr-container">
        <h1> ChatRooms</h1>
        <div class="cr-newroom">
            <input type="text" id="newRoomText" autocomplete="off">
            <input type="submit" id="createRoomBtn" value=" Create Room">
        </div>

        <div class="cr-roomlist">
            <ul class="roomlist">
            </ul>
        </div>
    </div>
</body>
</html>

如果需要更多信息/模块,请告诉我,我很乐意提供。

Update1:正如 alex-rokabilis 正确建议的那样,我已将 $('.roomlist').html() = '' 更改为 $('.roomlist').html(''),但是问题仍然存在。

【问题讨论】:

    标签: javascript node.js socket.io


    【解决方案1】:

    我不确定这是否是您的问题的原因,但您正在获得嵌套列表元素,因为您的 socket.on ('roomupdate') 函数中有两个打开的 &lt;li&gt; 标记

    【讨论】:

      【解决方案2】:

      我认为问题在于如何在 html 部分呈现房间,而不是 socket.io 如何发送数据。 您使用 $('.roomlist').html=''; 但这并没有做任何事情! .html 是 jquery 中的一个函数,所以正确的做法是 $('.roomlist').html('');

      所以基本上你并没有删除以前的房间,而是只添加了更多重复的房间。另外,我注意到这不是您问题的一部分,在您使用的 nodejs 代码中:socket.broadcast.emit('roomupdate', JSON.stringify(rooms)); socket.emit('roomupdate', JSON.stringify(rooms));

      如果你想向所有连接的客户端广播一些东西,它有一个函数,也不需要对你的数据进行字符串化,socketio 会在内部为你做这件事!所以你可以使用这样的东西: io.emit('roomupdate',rooms);

      【讨论】:

      • 感谢指出jquery错误,但并没有解决问题。另外,我使用的是旧版本的套接字,所以你的代码不起作用,但我肯定会在我的下一个项目中使用你的推荐!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-14
      • 2017-09-14
      • 2017-08-04
      • 2015-08-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多