我在项目前端使用JavaScript EventSource。
有时,浏览器和服务器之间的连接失败或服务器崩溃。在这些情况下,EventSource试图在3秒后重新连接,如文档中所述。
但它只试了一次。如果仍然没有连接,则EventSource停止尝试重新连接,用户必须刷新浏览器窗口才能再次连接。
我怎么才能阻止这种行为?我需要EventSource尝试永远重新连接,而不仅仅是一次。
浏览器是Firefox。
发布于 2014-02-18 06:52:57
我通过实现一个“保持生存”的系统来处理这个问题;如果浏览器为我重新连接,这是很好的,但是我认为有时它不能工作,而且不同的浏览器可能会有不同的行为。
我在我的书的第五章中花了几页篇幅(公然的插件,在O‘’Reilly这里找到它:使用HTML5 SSE的数据推送应用程序),但是如果你想要一个非常简单的解决方案,不需要任何后端更改,设置一个全局计时器,在30秒后触发。如果它触发,那么它将杀死EventSource对象并创建另一个对象。拼图的最后一部分是在事件侦听器中:每次从后端获取数据时,杀死定时器并重新创建它。也就是说,只要你至少每30秒得到一次新的数据,计时器就永远不会触发。
下面是一些最起码的代码来说明这一点:
var keepAliveTimer = null;
function gotActivity(){
if(keepaliveTimer != null)clearTimeout(keepaliveTimer);
keepaliveTimer = setTimeout(connect, 30 * 1000);
}
function connect(){
gotActivity();
var es = new EventSource("/somewhere/");
es.addEventListener('message', function(e){
gotActivity();
},false);
}
...
connect();还要注意,我在连接之前调用了gotActivity()。否则,如果一个连接失败,或者在它有机会传递任何数据之前就死了,它就会被忽略。
顺便说一句,如果你也能改变后端,在25到30秒的安静之后,发送一条空白消息(“心跳”)是值得的。否则前端就得假设后端已经死了。当然,如果您的服务器发送的定期消息间隔不超过25-30秒,则不需要做任何事情。
如果您的应用程序依赖于Event报头,那么要意识到您的“保持生存”系统必须模拟这个过程;这会涉及到更多的问题。
发布于 2019-01-06 19:18:30
根据我的经验,如果存在网络级错误,浏览器通常会重新连接,但如果服务器使用HTTP错误(例如状态500)进行响应,则不会重新连接。
我们的团队制作了一个简单的包装库,用于在所有情况下重新连接:重新连接-事件源。也许会有帮助。
发布于 2019-01-27 06:08:47
下面,我演示了一种以合理的速度永远重新连接的方法。
这段代码使用了一个uses函数以及重新连接间隔加倍。在我测试的时候,效果很好。它以1秒、4、8、16...up连接,最长64秒,并以相同的速率重新尝试。
function isFunction(functionToCheck) {
return functionToCheck && {}.toString.call(functionToCheck) === '[object Function]';
}
function debounce(func, wait) {
var timeout;
var waitFunc;
return function() {
if (isFunction(wait)) {
waitFunc = wait;
}
else {
waitFunc = function() { return wait };
}
var context = this, args = arguments;
var later = function() {
timeout = null;
func.apply(context, args);
};
clearTimeout(timeout);
timeout = setTimeout(later, waitFunc());
};
}
// reconnectFrequencySeconds doubles every retry
var reconnectFrequencySeconds = 1;
var evtSource;
var reconnectFunc = debounce(function() {
setupEventSource();
// Double every attempt to avoid overwhelming server
reconnectFrequencySeconds *= 2;
// Max out at ~1 minute as a compromise between user experience and server load
if (reconnectFrequencySeconds >= 64) {
reconnectFrequencySeconds = 64;
}
}, function() { return reconnectFrequencySeconds * 1000 });
function setupEventSource() {
evtSource = new EventSource(/* URL here */);
evtSource.onmessage = function(e) {
// Handle even here
};
evtSource.onopen = function(e) {
// Reset reconnect frequency upon successful connection
reconnectFrequencySeconds = 1;
};
evtSource.onerror = function(e) {
evtSource.close();
reconnectFunc();
};
}
setupEventSource();https://stackoverflow.com/questions/21831206
复制相似问题