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

WebSocket报错:Cannot set properties of null (setting 'onmessage') 求助

问题分析与修复方案

错误根源

你在response()方法的第一行就执行了this.socketRef = null,直接将WebSocket实例置空,后续尝试给null设置onmessage属性,必然触发Cannot set properties of null错误。


1. 修复WebSocketService的response方法

移除错误的null赋值,同时完善连接状态校验与Promise的异常处理:

class WebSocketService {
  ...
  constructor() {
    this.socketRef = null;
  }

  // 新增连接初始化方法(确保先建立连接再监听消息)
  connect(wsUrl) {
    this.socketRef = new WebSocket(wsUrl);
    return new Promise((resolve, reject) => {
      this.socketRef.onopen = () => resolve("连接成功");
      this.socketRef.onerror = (err) => reject(err);
    });
  }
  ...
  response() {
    // 移除 this.socketRef = null; 这行错误代码
    return new Promise((resolve, reject) => {
      // 先校验WebSocket是否处于可用状态
      if (!this.socketRef || this.socketRef.readyState !== WebSocket.OPEN) {
        reject(new Error("WebSocket未连接或已关闭"));
        return;
      }

      this.socketRef.onmessage = e => {
        try {
          const response = JSON.parse(e.data);
          console.log(`!!!! response: ${JSON.stringify(response)} !!!`);
          resolve(response);
        } catch (parseErr) {
          reject(new Error(`解析消息失败:${parseErr}`));
        }
      };

      // 监听错误与关闭事件,避免Promise一直处于pending状态
      this.socketRef.onerror = (err) => reject(err);
      this.socketRef.onclose = () => reject(new Error("WebSocket连接已关闭"));
    });
  }
}

2. 修正useEffect的调用逻辑

确保先建立WebSocket连接,再调用监听方法,同时处理组件卸载时的清理:

useEffect(() => {
  let isComponentMounted = true;

  // 先建立连接,再监听服务器消息
  WebSocketInstance.connect("你的WebSocket服务地址")
    .then(() => WebSocketInstance.response())
    .then((res) => {
      if (!isComponentMounted) return;
      // 注意:res已经是JSON解析后的对象,无需再次解析res.text
      received.current = res?.data || "";
    })
    .catch((err) => {
      console.error("WebSocket处理异常:", err);
    });

  // 组件卸载时清理WebSocket连接
  return () => {
    isComponentMounted = false;
    if (WebSocketInstance.socketRef) {
      WebSocketInstance.socketRef.close();
      WebSocketInstance.socketRef = null;
    }
  };
}, []); // 空依赖确保只在组件挂载时执行一次

3. 额外注意事项

  • 驱动端的代码发送逻辑,必须在WebSocket连接成功后再触发,避免发送失败。
  • 如果需要持续监听服务器消息(而非仅接收一次),建议不要用Promise包裹onmessage,而是直接在connect方法中注册持久化的消息回调,或者提供专门的订阅方法管理监听函数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 23:55:18