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

Socket.io接收的客户端消息如何在EJS渲染中全局使用

解决方案

socket.on('chatMessage')回调内的msg是局部作用域变量,根路由无法直接访问。聊天场景需要存储历史消息而非单条临时消息,按以下步骤修改即可:

步骤1:定义全局可访问的消息存储

在server.js顶层作用域(和port、app这些变量同级,不要写在路由或socket回调内部)定义存储容器:

// 放在const port = process.env.PORT || 3000 这行下面即可
const messageHistory = [];

步骤2:收到消息时同步存入全局存储

修改socket.on('chatMessage')的回调逻辑,收到消息后先存入数组再广播:

//listen chatMessage
socket.on('chatMessage', msg =>{
  // 新消息写入全局历史数组
  messageHistory.push(msg);
  io.emit('message',msg);
  console.log(msg);
});

如果需要把用户上下线、欢迎语这类系统消息也展示给新进入的用户,在对应的socket.emit/io.emit触发位置,同步把消息内容push到messageHistory即可。

步骤3:根路由传入消息数据给EJS模板

修改根路由的渲染逻辑,直接传入全局存储的消息数组:

app.get("/", (req,res) =>{
  res.render("index",{messagedata: messageHistory});
});

步骤4:前端完成历史消息渲染+实时消息追加

注意:路由渲染只在用户首次打开页面时执行,用来加载历史消息;后续的新消息靠Socket.io实时推送更新,两部分逻辑都要补上:

  • 在EJS模板中遍历messagedata渲染初始历史消息
  • 修改客户端socket.on('message')回调,把收到的实时消息追加到页面消息列表中

参考客户端实现代码:

const socket = io();

const user_send =document.querySelector(".send-btn");
const user_msg=document.querySelector(".input-msg");
// 获取页面上的消息列表容器,对应HTML里<ul class="msg-container"></ul>这类结构
const msgContainer = document.querySelector(".msg-container");

// 渲染EJS传入的历史消息
<% messagedata.forEach(function(msg){ %>
  const msgItem = document.createElement('li');
  msgItem.textContent = '<%= msg %>';
  msgContainer.appendChild(msgItem);
<% }) %>

//message from server
socket.on('message',message=>{
  console.log(message);
  // 把实时收到的消息追加到页面
  const msgItem = document.createElement('li');
  msgItem.textContent = message;
  msgContainer.appendChild(msgItem);
  // 发送后清空输入框
  user_msg.value = '';
})

//getting socketid from server
socket.on('socketid',socketid=>{
  console.log(socketid);
});

//ading eventlistner in message send button
user_send.addEventListener("click",()=>{
  //get mesage from text filed
  const msg = user_msg.value;
  // 空消息不发送
  if(!msg.trim()) return;
  //emit message to server
  socket.emit('chatMessage',msg);
});

补充说明

  • 当前实现的消息存在服务端内存中,服务重启后所有消息会清空。如果需要永久保存消息,可以用你已经引入的mysql模块,收到消息时同步写入数据库,根路由渲染时从数据库读取消息传入模板即可。
  • 不建议用单个全局字符串变量存储单条消息,否则新用户进入页面只能看到最后一条消息,不符合聊天应用的使用逻辑。如果确实只需要最新一条消息,把顶层的数组替换为let latestMsg = '',收到消息时赋值latestMsg = msg,路由传入latestMsg即可。

内容的提问来源于stack exchange,提问作者Kushal Chapagain

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 02:48:37