-->

如何等待的WebSocket的readyState设置为改变(How to wait for a W

2019-06-21 07:29发布

我试图实现与回退到轮询的WebSocket。 如果WebSocket连接成功, readyState变为1,但如果失败, readyState是3,我应该开始投票。

我想是这样的:

var socket = new WebSocket(url);
socket.onmessage = onmsg;
while (socket.readyState == 0)
{
}
if (socket.readyState != 1)
{
    // fall back to polling
    setInterval(poll, interval);
}

我期待socket.readyState异步更新,并让我立即读它。 然而,当我运行它,我的浏览器冻结(我把它打开约半分钟之前放弃)。

我想也许有一个onreadyStateChanged事件,但我没有看到一个在MDN参考。

我应该如何实现呢? 显然,一个空的循环将无法正常工作,并没有事件此。

Answer 1:

这是简单的,它完美地工作......你可以添加条件有关最大时间,或尝试的数量,以使其更加坚固...

function sendMessage(msg){
    // Wait until the state of the socket is not ready and send the message when it is...
    waitForSocketConnection(ws, function(){
        console.log("message sent!!!");
        ws.send(msg);
    });
}

// Make the function wait until the connection is made...
function waitForSocketConnection(socket, callback){
    setTimeout(
        function () {
            if (socket.readyState === 1) {
                console.log("Connection is made")
                if (callback != null){
                    callback();
                }
            } else {
                console.log("wait for connection...")
                waitForSocketConnection(socket, callback);
            }

        }, 5); // wait 5 milisecond for the connection...
}


Answer 2:

这里有一个更详细的解释。 首先,检查特定的浏览器API,因为不是所有的浏览器将是最新的RFC。 您可以咨询

你不想跑一个循环,不断检查readyState的,这是额外的开销,你不需要。 更好的方法是了解所有相关的readyState的变化事件,然后适当地将它们连接起来。 它们分别是:

onclose事件侦听器时的WebSocket连接的readyState的改变为CLOSED被调用。 侦听器能够接收一个名为“关闭”的closeEvent。

onerror发生错误时被调用的事件侦听器。 这个被命名为“错误”一个简单的事件。

onmessage一个事件监听器,当从服务器接收到的消息被调用。 侦听器能够接收一个名为“消息” MessageEvent事件。

onopen被称为一个事件监听器当WebSocket连接的readyState的改变打开; 这表示连接是准备好发送和接收数据。 本次活动是一个简单的名称为“开放”。

JS完全是事件驱动的,所以你需要刚丝了所有这些事件并检查readyState的,这样你可以从WS相应切换到轮询。

我建议你看一下Mozilla的参考,更容易比RFC文档阅读,它会给你的API的一个很好的概述,以及它是如何工作的:看https://developer.mozilla.org/en-US/docs/的WebSockets / WebSockets_reference /的WebSocket

不要忘了做一个回调重试,如果你有一个失败,民意调查,直到成功重新连接回调被触发。



Answer 3:

看看上http://dev.w3.org/html5/websockets/

搜索“事件处理程序”,找到表。

的OnOpen - >打开
的onMessage - >消息
onError的 - >错误
OnClose中 - >关闭

function update(e){ /*Do Something*/};
var ws = new WebSocket("ws://localhost:9999/");

ws.onmessage = update;


Answer 4:

我不使用池的。 相反,我使用排队。 首先,我创建新的发送功能和队列:

var msgs = []
function send (msg) {
  if (ws.readyState !== 1) {
    msgs.push(msg)
  } else {
    ws.send(msg)
  }
}

然后,我需要阅读并当第一次建立的连接发送:

function my_element_click () {
  if (ws == null){
    ws = new WebSocket(websocket_url)
    ws.onopen = function () {
      while (msgs.length > 0) {
        ws.send(msgs.pop())
      }
    }
    ws.onerror = function(error) {
      // do sth on error
    }
  } 
  msg = {type: 'mymessage', data: my_element.value}
  send(JSON.stringify(msg))
}

在这个例子中WebSocket连接仅在第一次点击创建。 通常情况下,对第二消息开始被直接发送。



Answer 5:

while循环可能是锁定了你的线程。 尝试使用:

setTimeout(function(){
    if(socket.readyState === 0) {
        //do nothing
    } else if (socket.readyState !=1) {
        //fallback
        setInterval(poll, interval);
    }
}, 50);


Answer 6:

在我的使用情况下,我想在屏幕上显示一个错误,如果连接失败。

let $connectionError = document.getElementById("connection-error");

setTimeout( () => {
  if (ws.readyState !== 1) {
    $connectionError.classList.add( "show" );
  }
}, 100 );  // ms

需要注意的是在Safari(9.1.2)没有error事件被炒鱿鱼-否则我会放在这个错误处理程序。



Answer 7:

就像你定义的onmessage处理程序,您还可以定义一个onerror处理程序。 当连接失败这一个将被调用。

var socket = new WebSocket(url);
socket.onmessage = onmsg;
socket.onerror = function(error) {
    // connection failed - try polling
}


文章来源: How to wait for a WebSocket's readyState to change