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

如何在Deno中读取WebSocket返回的Blob数据?

问题描述

我正在尝试在Deno中通过WebSocket读取AISstream的数据,相关代码如下(需使用AISstream提供的API密钥才能运行):

/**
 * URL used by the API; this might change if the version changes or at any time, since it's experimental
 */
const AIS_API_URL = "wss://stream.aisstream.io/v0/stream";

export const defaultBoundingBox = [
  [
    [-90, -180],
    [90, 180],
  ],
];

let socket = null;

// Creates a deno websocket client and subscribes to the AIS API
export function createSocket(apiKey, boundingBoxes = defaultBoundingBox) {
  if (socket) {
    return socket;
  }
  socket = new WebSocket(AIS_API_URL);

  socket.onopen = () => {
    console.log("Socket connected");
    socket.send(
      JSON.stringify({
        apiKey,
        boundingBoxes,
      })
    );
  };

  socket.onmessage = (event) => {
    const reader = new FileReader();
    console.log(event);
    const decodedBlob = reader.readAsText(event.data);
    console.log(decodedBlob);
  };

  socket.onclose = () => {
    console.log("Socket closed");
  };
  return socket;
}

问题出在onmessage回调中:消息已成功接收,但event.data是Blob类型。我尝试用TextDecoder和readAsText解码,结果都返回undefined。在普通JavaScript中,event.data是字符串,可直接解析为JSON,但我无法解决Deno中的这个问题。


解决方案

Deno中WebSocket返回的Blob无法同步读取内容,FileReader.readAsText是异步操作,会立即返回undefined,必须通过异步方式获取结果。以下是两种可行的解决方法:

方法一:使用Blob自带的text()方法(推荐)

Blob实例的text()方法返回Promise,配合async/await可直接获取文本内容,代码更简洁:

socket.onmessage = async (event) => {
  if (event.data instanceof Blob) {
    const text = await event.data.text();
    const aisData = JSON.parse(text);
    console.log(aisData);
  }
};

方法二:监听FileReader的load事件

如果坚持使用FileReader,需要通过监听load事件获取解码后的结果:

socket.onmessage = (event) => {
  const reader = new FileReader();
  reader.onload = () => {
    const text = reader.result;
    const aisData = JSON.parse(text);
    console.log(aisData);
  };
  reader.readAsText(event.data);
};

完整修正后的代码

/**
 * URL used by the API; this might change if the version changes or at any time, since it's experimental
 */
const AIS_API_URL = "wss://stream.aisstream.io/v0/stream";

export const defaultBoundingBox = [
  [
    [-90, -180],
    [90, 180],
  ],
];

let socket = null;

// Creates a deno websocket client and subscribes to the AIS API
export function createSocket(apiKey, boundingBoxes = defaultBoundingBox) {
  if (socket) {
    return socket;
  }
  socket = new WebSocket(AIS_API_URL);

  socket.onopen = () => {
    console.log("Socket connected");
    socket.send(
      JSON.stringify({
        apiKey,
        boundingBoxes,
      })
    );
  };

  // 使用Blob.text()方法解码并解析数据
  socket.onmessage = async (event) => {
    try {
      const text = await event.data.text();
      const aisData = JSON.parse(text);
      console.log(aisData);
    } catch (err) {
      console.error("解码或解析数据失败:", err);
    }
  };

  socket.onclose = () => {
    console.log("Socket closed");
    socket = null; // 关闭后重置socket,允许重新创建连接
  };

  socket.onerror = (err) => {
    console.error("Socket错误:", err);
  };

  return socket;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 10:25:58