服务器发送的事件:如何以跨浏览器的方式自动重新连接
Server-sent events: How do you automatically reconnect in a cross-browser way?
我实现了一些代码来查询数据库中的任何更改并发送事件。这是我的PHP脚本的代码
header("Content-Type: text/event-stream");
header('Cache-Control: no-cache');
//****Some code here to query the database
echo "event: message'n";
echo "data: change_from_database 'n";
echo "'n'n";
ob_flush();
flush();
我依靠浏览器在每次连接关闭时自动重新连接,所以我没有在服务器代码上实现任何循环。此外,我从这个线程中了解到实现无限循环有很多缺点。
所以客户端一切都工作得很好:每次连接关闭时浏览器都会重新连接,每次服务器发送一个事件时都会触发一个事件;除了Firefox(40.0.2)不能重新连接。我知道它没有,因为我写了一些JavaScript错误检查代码来测试这个:
var evtSource = new EventSource("../sse.php");
evtSource.onerror = function(event){
var txt;
switch( event.target.readyState ){
case EventSource.CONNECTING:
txt = 'Reconnecting...';
break;
}
console.log(txt);
}
因此,大约每秒钟之后,chrome上的控制台记录"Reconnecting"
。另一方面,Firefox只重新连接一次,以后就再也不连接了。
我怎么写代码使这个工作在Firefox,也许其他浏览器支持服务器发送的事件,但不自动重新连接?
使用最新版本的Firefox浏览器(44.0.2),您的代码可以完美地工作。但是,您可以在错误处理程序中像这样重新初始化EventSource
对象:
var evtSource = new EventSource("../sse.php");
var evtSourceErrorHandler = function(event){
var txt;
switch( event.target.readyState ){
case EventSource.CONNECTING:
txt = 'Reconnecting...';
break;
case EventSource.CLOSED:
txt = 'Reinitializing...';
evtSource = new EventSource("../sse.php");
evtSource.onerror = evtSourceErrorHandler;
break;
}
console.log(txt);
}
但是我强烈不建议你这样做,因为你的代码没有使用保持连接存活的好处(正如你所写的,你知道无限循环),所以浏览器只做简单的轮询(你可以在网络选项卡中看到)。我看不出有任何理由在不保持永久连接的情况下使用SSE而不是AJAX,用PHP显然很难维护永久连接。所以我假设在这种情况下使用简单的AJAX轮询。
您可以使用像https://github.com/Yaffle/EventSource这样的多边形填充,它应该将事件源功能添加到不支持的浏览器
用你的代码在我的网站上运行测试,一切都如预期的Firefox 44.0.2和php 5.5工作。我在Mozilla开发者网络上发现了一些有趣的事情,你不一定能分辨出v22以后的Firefox的错误信息是什么。也许是错误检查中的开关语句让你失望了。这是文章的链接。查看错误处理部分。
我的php代码与你的相同。为了防止我做了一些不同的事情,这是我的html代码。
<!DOCTYPE>
<html>
<head>
<title>SSE Test</title>
<meta charset="utf-8" />
<script>
var evtSource = new EventSource("sse.php");
evtSource.onerror = function(event){
var txt;
switch( event.target.readyState ){
case EventSource.CONNECTING:
txt = 'Reconnecting...';
break;
}
console.log(txt);
};
</script>
</head>
<body></body>
</html>
- 如何在用户按下F5键或单击浏览器时显示自定义的fancybox's后退/关闭按钮
- 如何允许web浏览器记住未以标准方式发送的表单字段
- 正在寻找一种跨移动浏览器兼容的方式,通过内置麦克风进行录制
- 浏览器之间的文本区域更新方式不同
- 使用浏览器在页面(客户端)上运行自定义JavaScript来模拟点击?怎么做
- 在 Chrome 扩展程序中创建自定义事件的最惯用方式
- Javascript或浏览器以不同的方式设置位置
- 谷歌地图API v3自定义光标在谷歌浏览器中的热点
- 当用户返回 UC 浏览器时,如何以编程方式禁用缓存
- 用我自己的自定义快捷方式覆盖浏览器快捷方式
- 如何检测以跨浏览器方式使用 Javascript 的 DOMParser 时的 XML 解析错误
- 工具提示是否有跨浏览器方式
- 在内容可编辑元素上按 Enter 时插入 BR 或 P 标签的跨浏览器方式
- 避免无响应脚本的跨浏览器方式
- ALT后跟Q(自定义快捷方式)不适用于javascript中的浏览器
- 将样式元素动态插入DOM的最后一种跨浏览器方式
- 用Angular的方式创建自定义浏览器返回操作
- 提交POST表单的最简单的跨浏览器方式是什么?
- 如何让浏览器从自定义协议打开文件
- 我可以指示浏览器运行自定义javascript函数之前,甚至开始一个web请求