我正在尝试使用node和socket.io根据书中的教程构建聊天服务器和客户端。前端代码如下:
<html>
<head>
<title>Socket.IO example application</title>
<style type = "text/css">
#input {
width: 200px;
}
#messages {
position: fixed;
top: 40px;
bottom: 8px;
left: 8px;
right: 8px;
border: 1px solid #EEEEEE;
padding: 8px;
}
</style>
</head>
<body>
Your message:
<input id = "input" type = "text" />
<div id = "messages"></div>
<script src = "http://localhost:4001/socket.io/socket.io.js"></script>
<script type = "text/javascript">
var messagesElement = document.getElementById('messages');
var lastMessageElement = null;
function addMessage (message) {
var newMessageElement = document.createElement('div');
var newMessageText = document.createTextNode(message);
newMessageElement.appendChild(newMessageText);
messagesElement.insertBefore(newMessageElement, lastMessageElement);
lastMessageElement = newMessageElement;
}
var socket = io.connect('http://localhost:4001');
socket.on('login', function() {
var username = prompt('What username would you like to use?');
socket.emit('login', username);
});
socket.on('serverMessage', function (content) {
addMessage(content);
});
function sendCommand(command, args) {
if(command === 'j') {
socket.emit('join', args);
} else {
alert('unknown command: ' + command);
}
}
function sendMessage(message) {
var commandMatch = message.match(/^\/(\w*)(.*)/);
if(commandMatch) {
sendCommand(commandMatch[1], commandMatch[2].trim());
} else {
socket.emit('clientMessage', message);
}
}
var inputElement = document.getElementById('input');
inputElement.onkeydown = function(keyboardEvent) {
if(keyboardEvent.keyCode === 13) {
sendMessage(inputElement.value);
inputElement.value = '';
return false;
} else {
return true;
}
};
</script>
</body>
</html>
后端是:
/*jslint node: true */
var httpd = require('http').createServer(handler);
var io = require('socket.io').listen(httpd);
var fs = require('fs');
function handler(req, res) {
"use strict";
fs.readFile(__dirname + '/index.html', function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error Loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
httpd.listen(4001);
io.sockets.on('connection', function (socket) {
"use strict";
socket.on('login', function(username) {
socket.set('username', username, function (err) {
if (err) {
throw err;
}
socket.emit('serverMessage', 'Currently logged in as ' + username);
socket.broadcast.emit('serverMessage', 'User ' + username + ' logged in');
});
});
socket.on('clientMessage', function (content) {
socket.emit('serverMessage', 'You said: ' + content);
socket.get('username', function (err, username) {
if (!username) {
username = socket.id;
}
socket.get('room', function (err, room) {
if (err) {
throw err;
}
var broadcast = socket.broadcast,
message = content;
if (room) {
broadcast.to(room);
}
broadcast.emit('serverMessage', username + ' said: ' + message);
});
});
});
socket.on('join', function (room) {
socket.get('room', function (err, oldRoom) {
if (err) {
throw err;
}
socket.set('room', room, function (err) {
if (err) {
throw err;
}
socket.join(room);
if (oldRoom) {
socket.leave(oldRoom);
}
socket.get('username', function (err, username) {
if (!username) {
username = socket.id;
}
socket.emit('serverMessage', 'You joined room' + room);
});
socket.get('username', function (err, username) {
if (!username) {
username = socket.id;
}
socket.broadcast.to(room).emit('serverMessage', 'User ' + username + ' joined this room');
});
});
});
});
socket.on('disconnect', function() {
socket.get('username', function (err, username) {
if (!username) {
username = socket.id;
}
socket.broadcast.emit('serverMessage', 'User ' + username + ' disconnected');
});
});
socket.emit('login');
});
我面临的问题是,每当新用户登录时,所有之前的用户都会在新用户登录之前收到一条消息“User”+ randomID +“disconnected”,并且它正常运行。如果新用户在前一个用户登录后快速登录,则不会出现此问题(我猜测这与心跳有关)。我非常感谢任何帮助,找出每次新用户登录时为什么会触发此断开事件。谢谢。
答案 0 :(得分:1)
alert
或prompt
是阻止功能,它们会停止浏览器上的所有javascript事件。
这就是为什么socket.io中的'heart'会停止跳动。
更详细:
在每次心跳中,服务器都会向客户端发送一个数据包,以检查客户端是活还是死,如果客户端没有响应,服务器会认为它已经死了。
解决方案是用异步函数,弹出div,表单等替换prompt
函数...
答案 1 :(得分:0)
我一直在复制你的代码,并在我的服务器上运行,我找不到你的问题你面临的问题,但我发现一个问题,当我取消usename输入窗口时,我的用户名是null,我发现我的用户ID是随机字符串。当我断开连接时,socket.io将会这样一个消息,
“用户”+ randomID +“已断开连接”