Javascript WebSocket:如何在它死后自动重新连接
当我第一次连接到套接字时,我必须首先向服务器发送一条消息以验证我自己并订阅频道 我遇到的问题是,有时套接字服务器不可靠,会触发Javascript WebSocket:如何在它死后自动重新连接,javascript,websocket,Javascript,Websocket,当我第一次连接到套接字时,我必须首先向服务器发送一条消息以验证我自己并订阅频道 我遇到的问题是,有时套接字服务器不可靠,会触发'ws'对象的onerror和onclose事件 问:什么是好的设计模式,允许我在套接字关闭或遇到错误时等待10秒钟,然后重新连接到套接字服务器(并将初始消息重新发送到服务器)以下是我的结论。这对我来说很有用 var ws = new WebSocket('ws://localhost:8080'); ws.onopen = function () { ws.send
'ws'
对象的onerror
和onclose
事件
问:什么是好的设计模式,允许我在套接字关闭或遇到错误时等待10秒钟,然后重新连接到套接字服务器(并将初始消息重新发送到服务器)以下是我的结论。这对我来说很有用
var ws = new WebSocket('ws://localhost:8080');
ws.onopen = function () {
ws.send(JSON.stringify({
.... some message the I must send when I connect ....
}));
};
ws.onmessage = function (e) {
console.log('Got a message')
console.log(e.data);
};
ws.onclose = function(e) {
console.log('socket closed try again');
}
ws.onerror = function(err) {
console.error(err)
};
最新答复:
最后,(如果您不使用java),我发现您最好实现自己的“乒乓”策略。(如果您使用的是java,请看一看乒乓球的“动作类型”,我记得不是很清楚…)
在原生Websocket api之上有一个太有趣的包装器,无法很好地添加它
这对我使用
setInterval
有效,因为客户端连接可能会丢失
function connect() {
var ws = new WebSocket('ws://localhost:8080');
ws.onopen = function() {
// subscribe to some channels
ws.send(JSON.stringify({
//.... some message the I must send when I connect ....
}));
};
ws.onmessage = function(e) {
console.log('Message:', e.data);
};
ws.onclose = function(e) {
console.log('Socket is closed. Reconnect will be attempted in 1 second.', e.reason);
setTimeout(function() {
connect();
}, 1000);
};
ws.onerror = function(err) {
console.error('Socket encountered error: ', err.message, 'Closing socket');
ws.close();
};
}
connect();
当套接字打开时,不要忘记调用clearInterval。我发现这个包可以解决Websocket连接的重新连接问题。它有一个可配置选项列表,其中一个选项是重新连接延迟增长因子,它决定重新连接延迟增长的速度。使用异步等待如果套接字关闭或服务器上发生任何错误,客户端将永远尝试每5秒自动连接一次
ngOnInit(): void {
if (window.location.protocol.includes('https')) {
this.protocol = 'wss';
}
this.listenChanges();
}
listenChanges(): void {
this.socket = new WebSocket(`${this.protocol}://${window.location.host}/v1.0/your/url`);
this.socket.onmessage = (event): void => {
// your subscription stuff
this.store.dispatch(someAction);
};
this.socket.onerror = (): void => {
this.socket.close();
};
this.socket.onopen = (): void => {
clearInterval(this.timerId);
this.socket.onclose = (): void => {
this.timerId = setInterval(() => {
this.listenChanges();
}, 10000);
};
};
}
这不是一个明确的react问题,但这里有一个react风格的答案: TLDR:您可以使用
setInterval
定期检查websocket连接状态,并在连接关闭时尝试重新连接
类TestComponent扩展了React.Component{
建造师(道具){
超级(道具);
this.state={};
this.connect=this.connect.bind(this);
}
componentDidMount(){
this.interval=setInterval(this.connect,1000);
}
组件将卸载(){
如果(this.ws)this.ws.close();
if(this.interval)clearInterval(this.interval);
}
连接(){
// https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/readyState
if(this.ws==undefined | |(this.ws&&this.ws.readyState==3)){
this.ws=newwebsocket(`ws://localhost:8080`);
this.ws.onmessage=(e)=>{
log(JSON.parse(e.data));
};
}
}
render(){
回来嘿!;
}
}
是否重新连接到以前连接到的同一个websocket?因为我正在使用websocket id发送消息,但如果它有新的websocket id,则很难将消息发送到特定的系统。@AlexanderDunaev,超时主要是作为一种简单的方法添加的,以避免在服务器不可用时进行过于激进的重新连接,即网络中断或本地调试服务器关闭。但总的来说,我认为立即重新连接然后以指数级增长的等待时间重新连接比固定的1秒等待稍微好一些。当连接关闭时,websocket实例会发生什么情况。它是垃圾收集的,还是浏览器建立了一堆未使用的对象?setTimeout(connect,1000)是一种更简洁、资源高效的延迟重新连接的方法。还可以考虑使用StimeTimeUT(Connect,Max.Min(10000,超时+=超时)),在第一次连接之前和每次成功连接后重置超时250。通过这种方式,连接过程中的错误条件将增加退避,但如果是一次性错误情况,则将快速重新连接-2505001000400080001000010000毫秒延迟的破坏性较小,但响应速度比10001000毫秒更快。我看到此代码的问题是,如果连接关闭,我们尝试再次打开连接,如果失败,那么我们将永远不会发出重试。github库的可能副本实际上可以作为一个简单连接中的newWebSocket()
的简单插件。我知道这个答案一般来说有点离题,但为了简单起见,使用这里提到的javascript库确实有效。是的,你是对的!不要使用这两个github回购协议。我们为什么不使用它们?第二个看起来很有用。你应该实施你的乒乓球策略。不要信任打开/关闭事件。请注意,在我撰写本文时,ReconnectingWebSocket不支持“binaryType”选项:它似乎有50%的时间会返回到“blob”,而缩小的JS根本不包含该功能。所以我就自己滚。
"use strict";
var ws = require("ws");
var url = 'ws://localhost:3000';
var openedSocket = null;
var timeInterval = 5000;
function connect() {
var client = new ws(url);
return new Promise((resolve, reject) => {
console.log("client try to connect...");
client.on("open", () => {
console.log(
"WEBSOCKET_OPENED: client connected to server at port %s", port);
openedSocket = true;
resolve(openedSocket);
});
client.on("message", (data) => {
console.log(data);
});
client.on("close", (err) => {
console.log("WEBSOCKET_CLOSE: connection closed %o", err);
openedSocket = false;
reject(err);
});
client.on("error", (err) => {
console.log("WEBSOCKET_ERROR: Error", new Error(err.message));
openedSocket = false;
reject(err);
});
});
}
async function reconnect() {
try {
await connect();
} catch (err) {
console.log("WEBSOCKET_RECONNECT: Error", new Error(err.message));
}
}
reconnect();
// repeat every 5 seconds
setInterval(() => {
if (openedSocket == false) {
reconnect();
}
}, timeInterval);
class TestComponent extends React.Component {
constructor(props) {
super(props);
this.state = {};
this.connect = this.connect.bind(this);
}
componentDidMount() {
this.interval = setInterval(this.connect, 1000);
}
componentWillUnmount() {
if (this.ws) this.ws.close();
if (this.interval) clearInterval(this.interval);
}
connect() {
// https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/readyState
if (this.ws === undefined || (this.ws && this.ws.readyState === 3)) {
this.ws = new WebSocket(`ws://localhost:8080`);
this.ws.onmessage = (e) => {
console.log(JSON.parse(e.data));
};
}
}
render() {
return <div>Hey!</div>;
}
}