Socket.IO实时聊天应用用户变量未定义问题求助
Socket.IO实时聊天应用用户追踪问题
在"userSet"事件中设置user变量后,该变量在事件外部变为undefined。尝试过以JSON形式传递用户名(如{msg: msg, user:user}),问题依旧。
服务端代码
const express = require("express"); const http = require("http"); const { Server } = require("socket.io"); const app = express(); const httpServer = http.createServer(app); const io = new Server(httpServer); app.use(express.static("./www")); app.use(express.urlencoded({ extended: false })); app.use(express.json()); const users = []; app.get("/", (req, res) => { res.sendFile(__dirname + "/www/index.html"); }); io.on("connection", (socket) => { console.log("Utente connesso"); console.log(users.toString()); socket.on("setUsername", (data) => { if (users.indexOf(data) > -1) { socket.emit("checkUser", "Il nome " + data + " è già stato preso. Riprova con un altro."); } else users.push(data); console.log("Benvenuto " + data); socket.emit("userSet", data); }); socket.on("messaggio", (data) => { console.log("mes: " + data); io.emit("mostraMessaggio", data); }); }); httpServer.listen(3000);
客户端代码
const socket = io(); var par; function setUsername() { socket.emit("setUsername", document.getElementById("username").value); } let user; socket.on("userSet", (data) => { user = data; alert("set " + user + " " + data); }); socket.on("checkUser", (data) => { alert(data); alert("c" + user); }); function inviaMessaggio() { const msg = document.getElementById("testo").value; alert("i " + user); if (msg) { socket.emit("messaggio", msg); } } socket.on("mostraMessaggio", (data) => { if (user) { par = document.createElement("p"); par.id = "messaggio"; par.innerHTML = user + ": " + data; document.getElementById("chat").appendChild(par); } });
问题分析与解决办法
核心问题
- 服务端逻辑漏洞:当用户名已存在时,仍会触发
userSet事件,导致客户端错误绑定已占用的用户名,后续操作中user变量因时序或重复触发出现异常。 - 客户端状态管理缺失:收到用户名占用提示时,未重置
user变量,导致后续发送消息时使用无效值。
修复步骤
1. 修正服务端逻辑
仅在用户名注册成功时发送userSet事件:
socket.on("setUsername", (data) => { if (users.indexOf(data) > -1) { socket.emit("checkUser", "Il nome " + data + " è già stato preso. Riprova con un altro."); } else { users.push(data); console.log("Benvenuto " + data); socket.emit("userSet", data); } });
2. 优化客户端状态处理
- 收到
checkUser提示时重置user变量:
socket.on("checkUser", (data) => { alert(data); user = undefined; // 清空无效的用户名状态 alert("c" + user); });
- 发送消息前校验
user有效性:
function inviaMessaggio() { const msg = document.getElementById("testo").value; if (!user) { alert("请先设置有效的用户名"); return; } if (msg) { socket.emit("messaggio", { user: user, msg: msg }); // 传递包含用户名的完整消息对象 } }
3. 调整消息收发逻辑
服务端转发完整消息数据,客户端正确解析发送者:
// 服务端修改messaggio事件处理 socket.on("messaggio", (data) => { console.log("mes: ", data); io.emit("mostraMessaggio", data); }); // 客户端修改mostraMessaggio事件处理 socket.on("mostraMessaggio", (data) => { par = document.createElement("p"); par.id = "messaggio"; par.innerHTML = data.user + ": " + data.msg; document.getElementById("chat").appendChild(par); });
内容的提问来源于stack exchange,提问作者ragna
相关产品推荐
相关产品推荐

