草庐IT

javascript - 在 HTML5 服务器发送事件中设置时间间隔

coder 2023-08-07 原文

我想从服务器向客户端发送定期更新。为此,我使用了服务器发送的事件。我正在粘贴以下代码:

客户端

获取服务器更新

<script>
if(typeof(EventSource)!="undefined")
{
   var source=new EventSource("demo_see.php");
   source.onmessage=function(event)
   {
      document.getElementById("result").innerHTML=event.data + "<br>";
   }
}
else
{
   document.getElementById("result").innerHTML="Sorry, your browser does not support    server-sent events...";
}
</script>
</body>
</html>

服务器端

<?php
    header('Content-Type: text/event-stream');
    header('Cache-Control: no-cache');
    $x=rand(0,1000);
    echo "data:{$x}\n\n";
    flush();
?>

该代码工作正常,但它每 3 秒 发送一次更新。我想以毫秒为单位发送更新。我在 flush() 之后尝试了 sleep(1) 但它只会将间隔进一步增加 1 秒。有谁知道我如何才能做到这一点?

另外,我可以使用服务器发送的事件发送图像吗?

最佳答案

正如上面评论中所讨论的那样,使用 sleepusleep 在无限循环中运行 PHP 脚本是不正确的,原因有两个

  • 当该脚本仍在运行时,浏览器将看不到任何事件数据(大概它会等待连接先关闭)。我记得 SSE 的早期浏览器实现允许这样做,但现在不再如此。
  • 即使它确实在浏览器端工作,您仍然会面临 PHP 脚本运行时间过长的问题(直到 PHP.ini time_out 设置生效)。如果这种情况发生一两次就可以了。如果有 X 千个浏览器同时从您的服务器寻找相同的 SSE,这将导致您的服务器崩溃。

正确的做法是让您的 PHP 脚本以事件流数据响应,然后像往常一样优雅地终止。如果您想控制浏览器重试的时间,请提供一个 retry 值(以毫秒为单位)。这是一些示例代码

function yourEventData(&$retry)
{
 //do your own stuff here and return your event data.
 //You might want to return a $retry value (milliseconds)
 //so the browser knows when to try again (not the default 3000 ms)
}

header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
header('Access-Control-Allow-Origin: *');//optional

$data = yourEventData($retry);

echo "data:{$str}\n\nretry:{$retry}\n\n";

作为对原始问题的回答,这有点但为了完整起见:

用这种方式轮询服务器得到的只是数据。之后你用它做什么完全取决于你。如果您想将这些数据视为图像并更新网页中显示的图像,您只需执行以下操作

document.getElementById("imageID").src = "data:image/png;base64," + Your event stream data;

关于这些原则。我有时忘记了 retry 必须以毫秒为单位并最终返回,例如 retry:5\n\n 令我惊讶的是,它仍然有效.但是,我会犹豫使用 SSE 以 100 毫秒的间隔更新浏览器端图像。更典型的用法是按照以下几行

  • 用户在服务器上请求作业。该作业要么排队在其他作业之后,要么可能需要相当多的时间来执行(例如创建 PDF 或 Excel 电子表格并将其发回)
  • 与其让用户在没有反馈的情况下等待 - 并冒着超时的风险 - 不如启动一个 SSE,告诉浏览器作业完成的预计到达时间,并设置一个 retry 值,这样浏览器知道何时再次查找结果。
  • ETA 用于向用户提供一些反馈
  • 在 ETA 结束时,浏览器将再次查看(浏览器会自动执行此操作,因此您无需执行任何操作)
  • 如果由于某种原因作业没有被服务器完成,它应该在事件流中指出它返回,例如data{"code":-1}\n\n 以便浏览器端代码可以优雅地处理这种情况。

还有其他使用场景 - 更新股票报价、新闻标题等。以 100 毫秒的间隔更新图像感觉 - 纯粹个人观点 - 就像滥用技术。


自从我发布这个答案到现在已经快 5 年了,它仍然经常被点赞。为了任何仍在使用它作为引用的人的利益——在我看来,在许多方面,SSE 是一种相当过时的技术。随着对 WebSockets 的广泛支持的出现,为什么还要费心做 SSE。除了其他任何事情之外,为每次浏览器端重试从浏览器设置和断开 HTTPS 连接的成本非常高。 WSS 协议(protocol)的效率要高得多。

如果你想实现 websockets 的阅读点

  1. Client Side
  2. Server side via PHP with Ratchet
  3. With Nginx and NChan

在我看来,PHP 不是一种处理 websockets 的好语言,而且 Ratchet 远非易于设置。 Nginx/NChan 路线要容易得多。

关于javascript - 在 HTML5 服务器发送事件中设置时间间隔,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16315137/

有关javascript - 在 HTML5 服务器发送事件中设置时间间隔的更多相关文章

  1. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  2. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  3. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  4. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

    在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

  5. ruby-on-rails - 使用 Sublime Text 3 突出显示 HTML 背景语法中的 ERB? - 2

    所以我在关注Railscast,我注意到在html.erb文件中,ruby代码有一个微弱的背景高亮效果,以区别于其他代码HTML文档。我知道Ryan使用TextMate。我正在使用SublimeText3。我怎样才能达到同样的效果?谢谢! 最佳答案 为SublimeText安装ERB包。假设您安装了SublimeText包管理器*,只需点击cmd+shift+P即可获得命令菜单,然后键入installpackage并选择PackageControl:InstallPackage获取包管理器菜单。在该菜单中,键入ERB并在看到包时选择

  6. ruby-on-rails - 启动 Rails 服务器时 ImageMagick 的警告 - 2

    最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru

  7. ruby-on-rails - s3_direct_upload 在生产服务器中不工作 - 2

    在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo

  8. ruby-on-rails - Ruby 检查日期时间是否为 iso8601 并保存 - 2

    我需要检查DateTime是否采用有效的ISO8601格式。喜欢:#iso8601?我检查了ruby​​是否有特定方法,但没有找到。目前我正在使用date.iso8601==date来检查这个。有什么好的方法吗?编辑解释我的环境,并改变问题的范围。因此,我的项目将使用jsapiFullCalendar,这就是我需要iso8601字符串格式的原因。我想知道更好或正确的方法是什么,以正确的格式将日期保存在数据库中,或者让ActiveRecord完成它们的工作并在我需要时间信息时对其进行操作。 最佳答案 我不太明白你的问题。我假设您想检查

  9. ruby-on-rails - 将 Ruby 中的日期/时间格式化为 YYYY-MM-DD HH :MM:SS - 2

    这个问题在这里已经有了答案:Railsformattingdate(4个答案)关闭4年前。我想格式化Time.Now函数以显示YYYY-MM-DDHH:MM:SS而不是:“2018-03-0909:47:19+0000”该函数需要放在时间中.现在功能。require‘roo’require‘roo-xls’require‘byebug’file_name=ARGV.first||“Template.xlsx”excel_file=Roo::Spreadsheet.open(“./#{file_name}“,extension::xlsx)xml=Nokogiri::XML::Build

  10. ruby-on-rails - Ruby url 到 html 链接转换 - 2

    我正在使用Rails构建一个简单的聊天应用程序。当用户输入url时,我希望将其输出为html链接(即“url”)。我想知道在Ruby中是否有任何库或众所周知的方法可以做到这一点。如果没有,我有一些不错的正则表达式示例代码可以使用... 最佳答案 查看auto_linkRails提供的辅助方法。这会将所有URL和电子邮件地址变成可点击的链接(htmlanchor标记)。这是文档中的代码示例。auto_link("Gotohttp://www.rubyonrails.organdsayhellotodavid@loudthinking.

随机推荐