每次用户添加新数据时,节点都会多次发回数据

首先,我想为可怕的标题道歉, 在过去的20分钟里,我一直在想一个人,但我不知道一个简洁的方式来描述我所遇到的问题。 如果有人有更好的build议,请让我知道或编辑标题,如果你能。

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

问题 :假设有一个空的列表,并且用户添加了一个新的房间,标题为“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-rokabilisbuild议的那样,我已经将$('.roomlist').html() = ''改为$('.roomlist').html('') ,但问题仍然存在。

我不确定这是不是你的问题的原因,但是你得到嵌套的列表方法,因为你的socket.on('roomupdate')函数中有两个开放的<li>标签

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

所以基本上你没有抹掉以前的房间,而只是增加了更多的重复项目。 还有一些我注意到,不是你的问题的一部分,在你使用的nodejs代码: socket.broadcast.emit('roomupdate', JSON.stringify(rooms)); socket.emit('roomupdate', JSON.stringify(rooms)); socket.broadcast.emit('roomupdate', JSON.stringify(rooms)); socket.emit('roomupdate', JSON.stringify(rooms));

如果你想广播一些东西给所有连接的客户端有一个function,也没有必要串联你的数据,socketio在内部为你做! 所以你可以使用这样的东西: io.emit('roomupdate',rooms);