Uncaught InvalidStateError:无法执行'发送'在'WebSocket&#

Uncaught InvalidStateError: Failed to execute 'send' on 'WebSocket':

本文关键字:发送 WebSocket Uncaught 执行 InvalidStateError      更新时间:2023-09-26

我正在尝试运行以下代码:

function smConnect() {
  ws = new WebSocket('ws://127.0.0.1:1805/');
  delete ws.URL;
  ws.onopen = function(response) {};
  ws.onmessage = function(response) {};
  ws.onclose = function(response) {};
  ws.onerror = function(error) {};
}
smConnect();
ws.send('message', 'hi');

但它返回给我这个错误:

Uncaught InvalidStateError:未能在"WebSocket"上执行"send":仍处于CONNECTING状态。

可能是什么问题?

你可以这样做,它添加了一些日志记录,发送你可以在构造函数之外处理的信息,你也可以在它自己的命名空间中抽象掉SocketWrapper(好吧,是的,它现在在窗口中:)

你可以检查开发工具(大多数浏览器中的F12),看看日志/错误中发生了什么,例如:这里它抛出了一个错误,因为没有可用的套接字:)

您不需要为所有事件提供值,只需为您需要的事件提供值(您的情况是onpen+可能是onmessage?)

(在定义的回调中,这将指向套接字,而不是SocketWrapper,SocketWraper也不提供ws变量,它有点私有,但我想它应该这样做)

SocketWrapper上有一个send方法,当你发送到一个关闭的流时,它会抛出一个错误,但如果它还没有打开,它会对消息进行排队,直到它被打开,然后将队列清空到websocket(所以在某种意义上,你不需要设置onopen回调,只需使用send方法添加它就可以了;)

(function(nameSpace) {
  function createMethod(method, options, stateCallback) {
    var that = this;
    this[method] = function() {
      if (stateCallback && stateCallback.apply) {
        stateCallback(method);
      }
      console.info(method);
      if (options[method] && options[method].apply) {
        options[method].apply(that, arguments);
      }
    };
  }
  function SocketWrapper(options) {
    var ws,
      events = ['onopen', 'onmessage', 'onclose', 'onerror'],
      i, len, prop = {
        opened: false,
        closed: false,
        error: false
      },
      method;
    if (typeof options === 'undefined' || !options) {
      throw 'ArgumentException: please add default constructor options';
    }
    
    this.queue = [];
    
    this.onEventTrigger = function(eventName) {
      var i, len;
      if (eventName === 'onopen') {
        prop.opened = true;
        prop.closed = false;
        // openend send queue
        if (this.queue.length > 0) {
          for (i = this.queue.length; --i >= 0;) {
            this.send.apply(this, this.queue[0]);
            this.queue.splice(0, 1);
          }
        }
      }
      if (eventName === 'onerror') {
        prop.error = true;
      }
      if (eventName === 'onclosed') {
        prop.opened = false;
        prop.closed = true;
      }
    };
    this.init = function() {
      var cb = this.onEventTrigger.bind(this);
      ws = new WebSocket(options.url);
      for (i = 0; i < events.length; i++) {
        method = events[i];
        createMethod.apply(ws, [method, options, cb]);
      }
    };
    this.send = function() {
      if (prop.closed) {
        throw 'InvalidOperation: Cannot send messages to a closed Websocket!';
      }
      if (!prop.opened) {
        this.queue.push(arguments);
      } else {
        ws.send.apply(ws, arguments);
      }
    };
    
    this.init();
    return this;
  }
  window.SocketWrapper = SocketWrapper;
}(window));
var socket = new window.SocketWrapper({
  url: 'ws://127.0.0.1:1805',
  onopen: function() {
    this.send('message', 'hi');
  },
  onmessage: function() {
    console.log(arguments);
  },
  onclose: function() {
    socket = null;
  },
  onerror: function() {
    console.log('error occured, oh no!');
    console.error(arguments);
  }
});
socket.send('i am message send to soon, but since i check the state of the ws object, i will be queued and send when appropriate');