在新连接上触发Socket.io断开连接事件

我正在尝试使用节点和socket.io构build一个聊天服务器和客户端,遵循书中的教程。前端代码如下所示:

<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'); }); 

我面临的问题是,每当有新用户login时,所有以前的用户在新用户login前都会收到“用户”+ randomID +“已断开”的消息,并且正常运行。 如果一个新用户在刚才上一个用户login之后很快login(我猜测它和心跳在这里有关系),就不会出现这个问题。 我真的很感激任何帮助,搞清楚为什么这个断开连接事件正在触发每次新用户login。谢谢。

在JavaScript中的alertprompt阻止function,他们停止浏览器上的所有JavaScript事件。

这就是为什么socket.io中的“心脏”停止跳动。

更详细地说:

在每一次心跳中,服务器都会向客户端发送一个数据包,以检查客户端是否活着,如果客户端没有响应,服务器认为它已经死亡。

解决方法是用asynchronous函数,popupdiv,窗体等replacepromptfunction…

我已经复制你的代码,并运行在我的服务器,我找不到你的问题是你面临的,但我发现一个问题,当我取消用户名input窗口,我的用户名为空,我发现我的用户名是随机string。 当我断开连接时,socket.io将登上这样的消息,

“用户”+ randomID +“断开”