First of all, I would like to apologize for the horribly worded title; I have been trying to think of one for the past 20 minutes but I do not know a succinct way to describe the problem I am having. If anyone has a better suggestion, please let me know or edit the title if you are able to.
Background: In order to learn NodeJS, I am creating a chat server. When the user clicks the createRoomBtn
, an event is created containing the name of the room the user just created, and sent to the socket.js
module in app.js
, app.js then appends the room to the array of rooms (these rooms are displayed as a list in the browser), and creates a broadcast event to all users including the active user.
Problem: Let's say there is an empty list, and user adds a new room, titled "NodeJS", this will display the room on the screen, and everything is fine and dandy. Now, if I was to add another room, Socket.io, for example, the browser renders the following result: Socket.io, NodeJS, NodeJS
. If I was to add "Javascript", the result would be Javascript, Socket.io, NodeJS, Socket.io, Node.JS
. Basically, the browser renders the list over and over again, and each time the list shrinks by one. I do not have the slightest idea of why this is happening. The weird thing is that if I press refresh, the browser renders the list correctly Javascript, Socket.io, NodeJS
. What is going on?
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>
Please let me know if more information/modules are required, and I will be happy to provide them.
Update1: As correctly suggested by alex-rokabilis, I have changed $('.roomlist').html() = ''
to $('.roomlist').html('')
, however, the problem continues to persist.
答案 0 :(得分:1)
我不确定这是否是您问题的原因,但是您已经获得了嵌套列表条件,因为您的socket中有两个打开的<li>
标签。(&#39 ; roomupdate&#39;)功能
答案 1 :(得分:0)
我认为问题是如何在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);