0Pricing
JavaScript Academy · 课时

发送和接收消息

使用 send 和 onmessage 交换数据。

发送和接收消息 是 CoddyKit 上的免费 JavaScript Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 JavaScript Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 JavaScript Academy 课程共包含 4 节课。

发送文本

连接打开后,socket.send(string) 会向服务器传输文本消息。

socket.onopen = () => {
  socket.send("ping");
};

使用 onmessage 接收消息

每个传入的帧都会触发 onmessage。数据位于 event.data 中。

socket.onmessage = (event) => {
  console.log("Received:", event.data);
};

JSON 消息封装

WebSockets 传输的是原始字符串。要发送结构化数据,请使用 JSON.stringify 序列化,并在接收后进行解析。

socket.send(JSON.stringify({ type: "chat", text: "hi" }));
socket.onmessage = (e) => {
  const msg = JSON.parse(e.data);
  console.log(msg.type, msg.text);
};

按消息类型路由

一种常见模式是:包含一个 type 字段,并根据它进行分派。

socket.onmessage = (e) => {
  const msg = JSON.parse(e.data);
  switch (msg.type) {
    case "chat": showChat(msg); break;
    case "presence": updatePresence(msg); break;
  }
};

发送二进制数据

send 也接受 ArrayBuffer、类型化数组和 Blob 作为二进制载荷。

const bytes = new Uint8Array([1, 2, 3, 4]);
socket.send(bytes.buffer);

接收二进制数据

使用 binaryType = "arraybuffer" 时,event.data 是一个 ArrayBuffer,您可以将它包装在类型化数组中。

socket.binaryType = "arraybuffer";
socket.onmessage = (e) => {
  if (e.data instanceof ArrayBuffer) {
    const view = new Uint8Array(e.data);
    console.log(view.length);
  }
};

使用 bufferedAmount 处理背压

bufferedAmount 会报告已排队但尚未发送的字节数。在大量向 socket 发送数据之前请先检查它,以避免内存无界增长。

if (socket.bufferedAmount < 1_000_000) {
  socket.send(payload);
}

心跳

定期发送 ping 消息,让双方都知道连接仍然存活,也避免中间设备关闭空闲连接。

setInterval(() => {
  if (socket.readyState === WebSocket.OPEN) {
    socket.send(JSON.stringify({ type: "ping" }));
  }
}, 30000);

通过 WebSocket 实现请求/响应

为传出的消息标记一个 id,并在匹配的回复到达时完成相应的待处理请求。

const pending = new Map();
function request(payload) {
  const id = crypto.randomUUID();
  socket.send(JSON.stringify({ id, ...payload }));
  return new Promise((res) => pending.set(id, res));
}
socket.onmessage = (e) => {
  const msg = JSON.parse(e.data);
  if (pending.has(msg.id)) { pending.get(msg.id)(msg); pending.delete(msg.id); }
};

打开前排队

如果消息可能在 socket 打开前发送,请先缓存消息,并在 onopen 中将它们全部发送出去。

const queue = [];
function safeSend(data) {
  if (socket.readyState === WebSocket.OPEN) socket.send(data);
  else queue.push(data);
}
socket.onopen = () => { queue.forEach((d) => socket.send(d)); queue.length = 0; };

验证传入数据

永远不要信任网络传入的数据。请将 JSON.parse 放在 try/catch 中,并在使用前验证数据结构。

socket.onmessage = (e) => {
  let msg;
  try { msg = JSON.parse(e.data); }
  catch { return; }
  if (typeof msg.type !== "string") return;
  handle(msg);
};

快速检查

测试消息传递。

回顾:发送和接收

您发送了文本和二进制数据,处理了 onmessage,将数据封装为 JSON,按类型进行路由,通过 bufferedAmount 监测背压,添加了心跳,并在 socket 打开前将消息排队。下一步:连接生命周期。

常见问题解答

「发送和接收消息」课时是免费的吗?

是的 — 「发送和接收消息」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 JavaScript Academy 课程的其余内容,请升级到 CoddyKit PRO。 JavaScript Academy 课程共包含 4 节课。

「发送和接收消息」这节课中我会学到什么?

使用 send 和 onmessage 交换数据。 你通过在浏览器中直接运行的动手代码来练习 JavaScript Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 JavaScript Academy 需要有经验吗?

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

「发送和接收消息」课时需要多长时间?

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

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

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

此课程中的所有课时

  1. 打开 WebSocket 连接
  2. 发送和接收消息
  3. 连接生命周期与错误
  4. 重新连接策略
← 返回 JavaScript Academy