0Pricing
Frontend Academy · 课时

WebSocket API:打开、消息、关闭与错误

创建 WebSocket 连接,在消息事件处理程序中收发消息,并处理连接错误和正常关闭。

WebSocket API:打开、消息、关闭与错误 是 CoddyKit 上的免费 Frontend Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Frontend Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Frontend Academy 课程共包含 4 节课。

为什么使用 WebSockets

HTTP 采用请求/响应模式。对于实时应用(聊天、多人游戏、实时更新),您需要持久的双向通信。WebSockets 为您提供单个 TCP 连接,该连接会一直保持打开状态,并允许双方随时发送消息。

创建 WebSocket

使用 ws:// 或 wss:// URL 构造 WebSocket。浏览器会处理升级握手。

const ws = new WebSocket('wss://api.example.com/realtime');

// Always use wss:// (secure) in production

四种事件

WebSocket 有四种事件类型:open(已连接)、message(已接收数据)、close(连接已结束)和 error(出现问题)。

ws.addEventListener('open', () => {
  console.log('Connected');
  ws.send(JSON.stringify({ type: 'subscribe', channel: 'updates' }));
});

ws.addEventListener('message', (event) => {
  const data = JSON.parse(event.data);
  console.log('Received:', data);
});

ws.addEventListener('close', (event) => {
  console.log('Closed:', event.code, event.reason);
});

ws.addEventListener('error', (event) => {
  console.error('Error:', event);
});

发送消息

请使用 ws.send()。它接受字符串、ArrayBuffers、Blob 对象或 ArrayBufferView。对于结构化数据,请先使用 JSON.stringify。

ws.send('hello');
ws.send(JSON.stringify({ type: 'chat', text: 'Hi' }));

// Binary:
const buffer = new ArrayBuffer(8);
ws.send(buffer);

接收消息

请检查 event.data——其类型与服务器发送的内容相匹配。对于对象载荷,请使用 JSON.parse。

ws.addEventListener('message', (event) => {
  // typeof event.data: string | ArrayBuffer | Blob
  if (typeof event.data === 'string') {
    const msg = JSON.parse(event.data);
    handleMessage(msg);
  }
});

连接状态(readyState)

请检查 ws.readyState:CONNECTING=0、OPEN=1、CLOSING=2、CLOSED=3。请勿在 OPEN 之前发送数据。

if (ws.readyState === WebSocket.OPEN) {
  ws.send(message);
} else {
  console.warn('Not connected yet');
}

正常关闭

请调用 ws.close(code, reason)。标准关闭代码包括:1000(正常)、1001(正在离开)、1008(违反策略)和 1011(服务器错误)。

ws.close(1000, 'User logged out');

重新连接策略

WebSockets 会因网络变化、服务器重启等原因断开。请使用指数退避实现重新连接。

let reconnectDelay = 1000;

function connect() {
  const ws = new WebSocket('wss://api/realtime');
  ws.addEventListener('open', () => { reconnectDelay = 1000; });
  ws.addEventListener('close', () => {
    setTimeout(connect, reconnectDelay);
    reconnectDelay = Math.min(reconnectDelay * 2, 30000);
  });
  return ws;
}

心跳与保活

空闲的 WebSockets 在约 60 秒后可能会被代理和负载均衡器终止。请每隔 25 至 30 秒发送一次 ping,以保持连接处于活动状态。

let pingInterval;
ws.addEventListener('open', () => {
  pingInterval = setInterval(() => {
    if (ws.readyState === WebSocket.OPEN) {
      ws.send(JSON.stringify({ type: 'ping' }));
    }
  }, 25000);
});
ws.addEventListener('close', () => clearInterval(pingInterval));

身份验证

WebSockets 不支持自定义标头。可选方案:1)在 WS URL 中通过查询字符串令牌(?token=jwt)进行身份验证。2)连接打开后发送身份验证消息。3)使用 Cookie(同源时会自动生效)。

// Query string:
const ws = new WebSocket(`wss://api/realtime?token=${jwt}`);

// Auth message:
ws.addEventListener('open', () => {
  ws.send(JSON.stringify({ type: 'auth', token: jwt }));
});

用于 WebSockets 的 React 钩子

请将 WS 生命周期封装在自定义钩子中,以避免连接泄漏。

function useWebSocket(url) {
  const [messages, setMessages] = useState([]);
  const wsRef = useRef(null);

  useEffect(() => {
    const ws = new WebSocket(url);
    wsRef.current = ws;
    ws.addEventListener('message', (e) => {
      setMessages(m => [...m, JSON.parse(e.data)]);
    });
    return () => ws.close();
  }, [url]);

  return { messages, send: (msg) => wsRef.current?.send(JSON.stringify(msg)) };
}

WebSocket、HTTP/2 与 SSE

WebSocket:全双工,双方都可以发送数据。HTTP/2 服务器推送:已弃用。Server-Sent Events:仅支持服务器到客户端,使用更简单,并且会自动重新连接。当客户端也需要发送数据(例如聊天)时请选择 WS;单向通知则适合使用 SSE。

快速检查

对于正常且有意执行的关闭(例如用户退出登录),标准的 WebSocket 关闭代码是什么?

回顾:WebSocket API

new WebSocket('wss://...') 会打开连接。四种事件:open、message、close 和 error。send() 接受字符串、ArrayBuffer 或 Blob;对象则使用 JSON.stringify。发送前请检查 readyState。正常关闭请使用 close(1000)。使用指数退避重新连接。每隔 25 秒发送一次心跳以保持连接。通过查询字符串或身份验证消息进行身份验证。在 React 中使用钩子进行封装。

常见问题解答

「WebSocket API:打开、消息、关闭与错误」课时是免费的吗?

是的 — 「WebSocket API:打开、消息、关闭与错误」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Frontend Academy 课程的其余内容,请升级到 CoddyKit PRO。 Frontend Academy 课程共包含 4 节课。

「WebSocket API:打开、消息、关闭与错误」这节课中我会学到什么?

创建 WebSocket 连接,在消息事件处理程序中收发消息,并处理连接错误和正常关闭。 你通过在浏览器中直接运行的动手代码来练习 Frontend Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Frontend Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Frontend Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「WebSocket API:打开、消息、关闭与错误」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Frontend Academy 课中编写并运行代码吗?

能。每节 Frontend Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. WebSocket API:打开、消息、关闭与错误
  2. Socket.io 客户端集成
  3. 用于单向流式传输的服务器发送事件
  4. 实时界面模式
← 返回 Frontend Academy