我正在尝试创建一个简单的NodeJS排行榜,并且正在使用socket.io进行客户端和服务器之间的实时连接。一切正常,但是按增加按钮后,页面崩溃了,我必须关闭它。在页面崩溃之前,我在浏览器控制台中看不到任何错误,并且在命令提示符中也没有错误,这是我从中运行应用程序的位置。
我想用socket.on('increase')
实现的目的是弄清楚表中是否已经存在作为参数给出的名称。如果是,则替换表另一列中的得分值,如果不是,则在表中添加一个新行,并使用用户名和得分。
不过,我不知道为什么页面崩溃了。但是,我很确定这与usernameForm
有关,因为当我删除它时,问题不再发生。
index.html
<!doctype html>
<html>
<body>
<form id="usernameForm">
<input type="text" id="usernameFormInput" name="usernameFormInput">
<input type="submit" value="Submit">
</form>
<div id="users"></div>
<button id="increase">Increase</button><br>
<span id="score">0</span><br>
<table id="leaderboard">
<tr>
<th>Name</th>
<th>Score</th>
</tr>
</table>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
var playerName = "Jeff";
var playerScore = 0;
document.getElementById("increase").onclick = function() {
playerScore += 1;
document.getElementById("score").innerHTML = playerScore;
socket.emit('increase', playerName, playerScore);
};
document.getElementById("usernameForm").onsubmit = function(e) {
var newUsername = document.getElementById("usernameFormInput").value;
socket.emit('newUser', newUsername);
console.log("new user client");
e.preventDefault();
}
socket.on('increase', function(user, score) {
for (i = 0; i < document.getElementById("leaderboard").rows.length; i++) {
if (document.getElementById("leaderboard").rows[i].cells[0].innerHTML == user) {
document.getElementById("leaderboard").rows[i].cells[1].innerHTML = score;
}
else {
var table = document.getElementById("leaderboard");
var row = table.insertRow(0);
var userCell = row.insertCell(0);
var scoreCell = row.insertCell(0);
userCell.innerHTML = user;
scoreCell.innerHTML = score;
}
}
});
socket.on('newUser', function(name) {
playerName = name;
console.log("new user client cb");
});
socket.on('updateUsers', function(usernames) {
document.getElementById('users').innerHTML = Object.values(usernames);
});
</script>
</body>
</html>
app.js
var io = require('socket.io')(http);
var usernames = [];
var userScore = {};
var isUsernameTaken = function(data) {
for (var i = 0; i <= Object.keys(usernames).length; i++) {
console.log("loop entered");
if(data == usernames[i]) {
console.log("Username '" + data + "' is taken.")
return true;
} else {
console.log("Username '" + data + "' is not taken.");
usernames.push(data);
updateUsers();
return false;
}
}
}
var updateUsers = function() {
io.emit('updateUsers', usernames);
console.log(usernames);
};
io.on('connection', function(socket) {
socket.on('increase', function(user, score) {
userScore[user] = score;
io.emit('increase', user, score);
});
socket.on('newUser', function(name) {
console.log("new user server");
if ( isUsernameTaken(name) ) {
console.log("username taken");
}
else {
console.log("new user server loop");
usernames.push(name);
io.emit('newUser', name);
}
});
});
http.listen(4000, function(){
console.log('listening on *:4000');
});
我对长代码的代码表示歉意,但是当我尝试维护MCVE时,我还需要包括所有相关代码以找出问题的根源。
答案 0 :(得分:1)
事件发射器是同步的。 .emit('increase'
似乎正在同步触发socket.on('increase'
,因此创建了一个使网页崩溃的无限循环。如果支持socket.once
,请尝试执行此操作;否则,在第一次触发socket.on('increase'
事件侦听器后,将其删除,如果此操作可以修复页面,则您知道原因所在。
答案 1 :(得分:1)
您的问题出在.insertRow上,您必须使用表长度的大小。
这是一个可能的解决方案:
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule } from '@angular/core';
// Importing Components
import { AppComponent } from './app.component';
import { ModalsComponent } from '@advent/components';
@NgModule({
declarations: [
AppComponent,
ModalsComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
由于它是复制行,所以我也对代码进行了一些更改