You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

问题分析与解决办法

核心问题

  1. 服务端逻辑漏洞:当用户名已存在时,仍会触发userSet事件,导致客户端错误绑定已占用的用户名,后续操作中user变量因时序或重复触发出现异常。
  2. 客户端状态管理缺失:收到用户名占用提示时,未重置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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 05:02:47