Javascript:正确地全球化Websocket发送函数
我正在使用WebSocket,并试图在整个应用程序中随时发送套接字数据。当我试图从另一个函数中访问send命令时,我收到:Javascript:正确地全球化Websocket发送函数,javascript,websocket,Javascript,Websocket,我正在使用WebSocket,并试图在整个应用程序中随时发送套接字数据。当我试图从另一个函数中访问send命令时,我收到: Uncaught InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable. 这仅在我调用函数时发生,这是我设置websocket的方式: Main.socket = (function() { var socket = new WebSocke
Uncaught InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable.
这仅在我调用函数时发生,这是我设置websocket的方式:
Main.socket = (function() {
var socket = new WebSocket("ws://server:port");
socket.onopen = function() {
console.log("Socket has been opened!");
}
function send() {
socket.send('test');
}
return {
socket: socket,
send: send
}
})();
我能够全局调用函数,并且当我从函数中调用console.log Main.socket时,它也能够看到套接字。但是当我调用send函数时,我得到了这个错误。问题是套接字尚未打开
WebSocket.send
在异步onopen
事件发生之前无法使用
当使用setTimeout
(持续足够长的时间)“应该工作”时,处理异步JavaScript编程的正确方法是将程序流视为一系列依赖事件
在任何情况下,下面是一个小示例,展示了如何使用一个(从jQuery 1.8开始,它没有被破坏并遵守合同):
然后,在使用这个小模块的代码中:
Main.socket.then(function (send) {
// This will only be called after `Promise.resolve` is called in the module
// which will be called in the `WebSocket.onopen` callback.
send("Hello world!");
})
// This code may or may not execute before the `then` function above
// depending upon the state the Promise/Deferred Object.
// However, we can get consistent program flow by using `then`-chaining
// of promises.
当然,您不必使用承诺-回调将很好地工作,尽管我更喜欢承诺的统一契约/框架-并且您可以使用任何最合适的名称或结构
另外,请注意,在整个页面生命周期中使用一个WebSocket可能不太好,因为这无法正确处理断开连接和恢复情况。这里有一个替代解决方案,用于等待web socket连接联机,替换您的呼叫:
function send() {
web_socket.send('test');
}
为此:
function send(msg) {
wait_for_socket_connection(socket, function() {
socket.send(msg);
});
};
function wait_for_socket_connection(socket, callback){
setTimeout(
function(){
if (socket.readyState === 1) {
if(callback !== undefined){
callback();
}
return;
} else {
console.log("... waiting for web socket connection to come online");
wait_for_socket_connection(socket,callback);
}
}, 5);
};
我怀疑这是因为套接字尚未打开-是否调用了
onopen
?“试图使用不可用或不再可用的[Socket]对象[因为它处于无效状态]。”如果我打开控制台并执行Main.Socket.send('test'),则套接字已打开;我可以在我的服务器上看到这一点,但当我尝试从函数内部调用时,它失败了。我已经在我的主套接字中添加了一个init函数,我在开始时调用它。如果打开主控制台并调用Main.socket.send,时间已经过了——而且时间足够长,套接字可能有足够的时间打开(同样重要的是,JavaScript代码一直处于空闲状态,因此事件已经被处理)。从失败的代码中尝试此操作:在setTimeout(函数(){Main.socket.send(“yay”)},500)
中调用send
。当然,这是一个愚蠢的等待时间,实际上我们应该只等待直到触发打开。使用futures可以简化这种链接,但它需要在消费者中异步使用。啊!这就成功了,所以我想我将编辑Main.init以获得延迟,以便websocket有时间连接。谢谢不,不,那只是一个丑陋的黑客。利用onopen回调并公开您自己的异步绑定。如果您使用的是jQuery1.8+,它可以创建一个Promise/a对象。
function send(msg) {
wait_for_socket_connection(socket, function() {
socket.send(msg);
});
};
function wait_for_socket_connection(socket, callback){
setTimeout(
function(){
if (socket.readyState === 1) {
if(callback !== undefined){
callback();
}
return;
} else {
console.log("... waiting for web socket connection to come online");
wait_for_socket_connection(socket,callback);
}
}, 5);
};