如何确定 SSE 连接已关闭
How to determine that an SSE connection was closed?
我们在 JavaScript 中打开了一个 SSE(服务器发送事件)连接,由于服务器重新启动或其他原因,该连接有时会关闭。在这种情况下,最好重新建立连接。怎么办?有没有办法在客户端找出连接已关闭?
在这里:https://developer.mozilla.org/en-US/docs/Web/API/EventSource 我只找到了一种关闭连接的方法,但没有回调或用于确定连接是否还处于活动状态的测试方法。
谢谢你的帮助。
如果连接关闭(以浏览器可以实现它的方式),它将自动连接。而且它往往会很快做到这一点(Chrome 中的默认值为 3 秒,Firefox 中的默认值为 5 秒)。 readyState
执行此操作时将连接 (0)。只有当一开始就出现一些连接问题(例如由于 CORS 问题)时,它才会关闭 (2)。关闭后,它不会重试。
我更喜欢在顶部添加保持活动机制,因为浏览器不能总是检测到死套接字(更不用说被锁定的远程服务器进程等)。有关详细代码,请参阅使用 HTML5 SSE 的数据推送应用程序的第 5 章,但基本上它涉及让服务器每 15 秒发送一条消息,然后运行 20 秒的 JavaScript 计时器,但每次收到消息时都会重置。如果计时器过期,我们将关闭连接并重新连接。
事件源 API 更新
事件源 API 现在有三个事件处理程序:
- 开错误
- 在消息中
- 开场
这些应该足以处理您在客户端所需的一切。
像这样:
const ssEvent = new EventSource( eventUrl );
ssEvent.onopen = function (evt) {
// handle newly opened connection
}
ssEvent.onerror = function (evt) {
// handle dropped or failed connection
}
ssEvent.onmessage = function (evt) {
// handle new event from server
}
参考: mozilla.org : 事件源 : 事件处理程序
浏览器对事件源 API 的支持:onopen - caniuse.com
检查readyState
属性:
var es = new EventSource();
// Сheck that connection is not closed
es.readyState !== 2;
// or
es.readyState !== EventSource.CLOSED;
最好不要尝试确定连接是否已关闭。我认为没有办法做到这一点。服务器端事件在所有浏览器中的工作方式都不同,但在某些情况下它们都会关闭连接。例如,Chrome 会在服务器重新启动时关闭 502 错误的连接。因此,最好按照其他人的建议使用保持活动状态,或者在每次错误时重新连接。保持活动状态仅在指定的时间间隔重新连接,必须保持足够长的时间间隔以避免服务器不堪重负。每次错误时重新连接都有尽可能低的延迟。但是,只有采用将服务器负载保持在最低水平的方法,才有可能。下面,我将演示一种以合理的速率重新连接的方法。
此代码使用去抖动功能以及重新连接间隔加倍。它运行良好,连接时间为 1 秒、4、8、16 秒......最长可达 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();
- 如何确定javascript已经完成了某些操作.ios上的
- 是否可以将一个函数输入连接到另一个函数调用的文本
- 如何使用密码检测网络中的状态连接
- 如何处理node.js节点mongodb中的连接和查询队列
- Rails-JQueryUIAutcomplete和AJAX不工作,可以't连接到数据库
- 如何使用jquery确定用户是否年满18岁
- Twilio-显示所有连接参与者的远程参与者视频
- 操作放置在画布上的元素之间的连接
- TypeError:_this.store.getState在使用来自Redux的连接时不是函数
- jQuery UI可排序-多连接列表拖动
- 如何使用offer/answer交换来自两个对等连接的流
- 有没有可能确定我博客的访问者的性别
- 如何确定 SSE 连接已关闭
- 了解用户是否连接到确定的wifi一段时间
- 确定 https 连接中使用的密码
- 如何在javascript中确定连接到网络与在线
- socket.io确定是否已连接到服务器
- 确定客户端的连接是否已断开
- 通过javascript或jquery确定用户的互联网连接类型
- 通过PHP或Javascript确定无线连接或电缆连接的任何方法