gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-04 01:08:18 24 4
gpt4 key购买 nike

我正在尝试按照书上的教程使用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”并且功能正常。如果新用户在前一个用户登录后快速登录,则不会出现此问题(我猜测这与此处的心跳有关)。我真的很感谢任何帮助找出每次新用户登录时触发此断开连接事件的原因。谢谢。

最佳答案

javascript 中的

alertprompt 是阻塞函数,它们会停止浏览器上的所有 javascript 事件。

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

更详细:

在每次心跳中,服务器都会向客户端发送一个数据包,用于检查客户端是存活还是死亡,如果客户端没有响应,则服务器认为客户端已死亡。

解决方案是用异步函数、弹出 div、表单等替换 prompt 函数...

关于javascript - Socket.io 在新连接上触发断开事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20684318/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com