在实时系统中(如:告警通知、聊天消息、订单提醒、监控系统),
前端通常需要:

一旦 WebSocket 收到消息,立刻在页面弹窗提示用户

下面我们一步一步来。


一、基本思路(先搞清楚)

整体流程非常简单:

  1. 前端建立 WebSocket 连接
  2. 监听 onmessage 事件
  3. 接收到消息后解析数据
  4. 触发弹窗 / 通知

二、原生 JavaScript 实现(最通用)

1️⃣ 建立 WebSocket 连接

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>WebSocket 实时弹窗</title>
</head>
<body>

<button onclick="connect()">连接 WebSocket</button>

<script>
let socket;

function connect() {
  socket = new WebSocket("ws://localhost:8080/ws");

  // 连接成功
  socket.onopen = () => {
    console.log("WebSocket 已连接");
  };

  // 接收消息(核心)
  socket.onmessage = (event) => {
    console.log("收到消息:", event.data);

    // 假设后端返回 JSON
    const data = JSON.parse(event.data);

    // 实时弹出
    showAlert(data.message);
  };

  // 连接关闭
  socket.onclose = () => {
    console.log("WebSocket 已断开");
  };

  // 发生错误
  socket.onerror = (err) => {
    console.error("WebSocket 错误", err);
  };
}

// 简单弹窗方法
function showAlert(msg) {
  alert("📢 实时通知:" + msg);
}
</script>

</body>
</html>

📌 关键点在这里:

socket.onmessage = (event) => {
  // 这里就是监听 WebSocket 消息的地方
};


三、使用更友好的页面弹窗(不使用 alert)

alert() 会阻塞页面,真实项目不推荐
下面用一个简单的 DOM 弹窗。

弹窗样式 + JS

<style>
#notify {
  position: fixed;
  top: 20px;
  right: 20px;
  background: #333;
  color: #fff;
  padding: 12px 18px;
  border-radius: 6px;
  display: none;
  z-index: 9999;
}
</style>

<div id="notify"></div>

<script>
function showAlert(msg) {
  const el = document.getElementById("notify");
  el.innerText = msg;
  el.style.display = "block";

  setTimeout(() => {
    el.style.display = "none";
  }, 3000);
}
</script>

效果:
✅ 右上角实时弹出
✅ 不阻塞页面
✅ 自动消失


四、Vue 项目中监听 WebSocket 并弹出

Vue 3 示例(setup 语法)

<script setup>
import { onMounted, onBeforeUnmount } from "vue";

let socket;

function connectWs() {
  socket = new WebSocket("ws://localhost:8080/ws");

  socket.onmessage = (event) => {
    const data = JSON.parse(event.data);
    showNotify(data.message);
  };
}

function showNotify(msg) {
  alert("通知:" + msg);
}

onMounted(() => {
  connectWs();
});

onBeforeUnmount(() => {
  socket && socket.close();
});
</script>

📌 注意
WebSocket 一般在:

  • 全局(App.vue)
  • 或单独封装成 ws.js

五、配合 UI 框架(真实项目推荐)

以 Element Plus 为例

import { ElNotification } from "element-plus";

socket.onmessage = (event) => {
  const data = JSON.parse(event.data);

  ElNotification({
    title: "系统通知",
    message: data.message,
    type: "warning",
    duration: 3000
  });
};

效果比 alert 专业很多,适合后台系统。


六、后端发送的消息格式(建议)

统一 JSON 格式,前端好处理:

{
  "type": "alarm",
  "message": "服务器 CPU 使用率超过 90%"
}

前端可以根据 type 决定不同弹窗样式。


七、常见坑 & 解决方案(很重要)

❌ 1. 页面刷新后 WebSocket 断开

✅ 解决:

  • 页面加载时自动重连
  • 或使用心跳 + 重连机制

❌ 2. 收到消息但没弹窗

检查:

  • 是否写在 onmessage
  • 是否 JSON.parse 报错
  • 是否被 try/catch 吃掉异常

建议:

socket.onmessage = (event) => {
  try {
    const data = JSON.parse(event.data);
    showAlert(data.message);
  } catch (e) {
    console.error("消息解析失败", e);
  }
};


❌ 3. 多次建立连接,弹窗重复

原因:

  • 组件反复 mounted
  • WebSocket 没有关闭

✅ 必须在销毁时:

socket.close();


八、进阶:消息类型区分

socket.onmessage = (event) => {
  const data = JSON.parse(event.data);

  switch (data.type) {
    case "alarm":
      showAlert("⚠️ " + data.message);
      break;
    case "info":
      showAlert("ℹ️ " + data.message);
      break;
  }
};


九、总结一句话

✔ WebSocket 实时监听核心在 onmessage
✔ 弹窗逻辑完全由前端控制
✔ alert 适合 demo,UI 通知适合生产
✔ 注意连接关闭与重复监听问题