HTML5数据推送SSE原理及应用开发

JavaScript表达行为,CSS表达外观,注意HTML既表达结构(逻辑结构),又表达内容(数据本身)通常需要更新数据时,并不需要更新结构,正是这种不改变组织结构仅改变数据的诉求,推动了数据拉取和数据推送技术的产生。

SSE是一种允许服务器端向客户端推送新数据(简称数据推送)的HTML5技术。数据推送有两种替代方案:无更新方案和数据拉取方案。

无更新方案:

加载完毕HTML之后,得到一个HTML页面,之后浏览器会请求图片、CSS文件和JavaScript文件等,他们都是浏览器可以缓存的静态文件。如果页面使用后端语言,比如PHP、Ruby和Python等为用户动态生成HTML的语言。

数据拉取方案:

浏览器会基于一些用户行为,或在一定时间之后,或基于某种别的触发方案,向服务器端请求或全部更新数据,通过javascript或一个meta标签能够命令整个页面重新加载。我们所熟悉的Ajax技术只被用于请求最新数据,当收到数据时,javascript函数会利用它来局部更新DOM。数据拉取的要义:仅拉取新数据,并且只更新页面中受影响部

以上的都不是数据推送,数据推送不是静态文件,也不涉及浏览器为更新数据而发起请求,数据推送是由服务器选择客户端发送新数据。

当数据源有新数据时,服务器端能立刻发送给一个或多个客户端,而不用等客户端来请求,这些新数据可能是突发新闻、最新股票、上线朋友的聊天信息、新的天气预报、策略游戏中的下一步等。

SSE适用于更新频繁、低延迟并且数据都是从服务端到客户端。它和WebSocket的区别:

1)便利,不需要添加任何新组件,用任何习惯的后端语言和框架就能继续使用,不用为新建虚拟机弄一个新的IP或新的端口号而劳神。

2)服务器端的简洁。因为SSE能在现有的HTTP/HTTPS协议上运作,所以它能够直接运行于现有的代理服务器和认证技术。

WebSocket相较SSE最大的优势在于它是双向交流的,这意味着服务器发送数据就像从服务器接受数据一样简单,而SSE一般通过一个独立的Ajax请求从客户端向服务端传送数据,因此相对于WebSocket使用Ajax会增加开销。因此,如果需要以每秒一次或者更快的频率向服务端传输数据,就应该用WebSocket。

具体代码如下:

html代码

复制代码
<!doctype html><html>
    <head>
        <meta charset="UTF-8">
        <title>basic SSE test</title>
    </head>
    <body>
        <pre id = "x">initializting...</pre>
        <!--之所以使用pre标签而不是p或者div是为了确保数据能以它被接受时的格式呈现,而不会修改或格式化-->

    </body>
    <script>
        var es = new EventSource("basic_sse.php");
        es.addEventListener("message",function(e){            //e.data
            document.getElementById("x").innerHTML += "\n"+e.data;
        },false);//使用false表示在冒泡阶段处理事件,而不是捕获阶段。
    </script></html>

需要注意的是:使用服务器端数据之前最好做一下检查,以防潜在的javascript注入攻击。

php代码

复制代码
<?php
    header('Content-Type: text/event-stream');
    header('Cache-Control: no-cache');
    $time = date('r');    echo "data: The server time is: {$time}\n\n";
    flush();?>

"Content-Type: text/event-stream"是专门为SSE设计的MIME类型,

效果截图

什么时候数据推送是错误的选择

首先考虑静态的情况,不引入数据推送,每当用户打开一个页面,在浏览器和服务器之间就会打开i一个套接字连接,服务器手机信息然后返回给用户,可能很简单,就像从磁盘上加载一个静态的HTML文件或一张图片一样,也可能很复杂,就像要运行一段用以连接很多数据库的后台语言。这里的关键点就是,一旦返回了所需的信息,套接字就会关闭,每个HTTP请求都会打开一个这种生命周期相对较短的套接字连接,这些套接字是服务器上有限的资源,每当它们完成既定任务,就会被回收以循环再利用。

现在对比看一下数据推送。一个请求永远不会完成,总是有很多信息要发送,所以套接字会一直保持打开状态显然,因为它们是有限的资源,所以同一时刻的SSE连接数会有限制。

想象一种情况,你在为你最新的应用提供电话服务支持,有10个接线中心员工为1000个用户提供服务,用户遇到问题,其中一个接线员接线,然后挂线。新的客户呼叫在排队,知道其中一个接线员挂线,这是典型的网络服务模式。

但是,现在有个客户打过来说,我现在没有问题,但是接下来几个小时都会用到你们的产品,并且如果遇到问题,我希望你们立即回复。这个客户将与接线员保持通话几个小时,那么呼叫中心的10%服务资源就被浪费。如果有10个这样的客户,那么其他990个客户就无法呼叫。这就是数据推送模式。

当然,这并不总是坏事,如果这个客户一下午每隔几秒钟就有一个问题,这种情况保持电话通畅不但没有浪费10%服务资源,反而会增加。因为每个问题都需要新打一个电话(就像数据拉取),接线员需要花额外的时间,验证客户身份,调出账户,降低服务效率。保持电话通常不仅使得客户更满意,也会提高呼叫中心的工作效率,这就是数据推送的最适合场景。

相关推荐
vvilkim1 分钟前
使用 JavaScript 和 HTML5 实现强大的表单验证
开发语言·javascript·html5
写完这行代码打球去1 分钟前
没有与此调用匹配的重载
前端·javascript·vue.js
华科云商xiao徐2 分钟前
使用CPR库编写的爬虫程序
前端
狂炫一碗大米饭4 分钟前
Event Loop事件循环机制,那是什么事件?又是怎么循环呢?
前端·javascript·面试
IT、木易6 分钟前
大白话Vue Router 中路由守卫(全局守卫、路由独享守卫、组件内守卫)的种类及应用场景
前端·javascript·vue.js
顾林海6 分钟前
JavaScript 变量与常量全面解析
前端·javascript
程序员小续6 分钟前
React 组件库:跨版本兼容的解决方案!
前端·react.js·面试
不会聊天真君6477 分钟前
HTML5(Web前端开发笔记第一期)
笔记·html5
乐坏小陈8 分钟前
2025 年你希望用到的现代 JavaScript 模式 【转载】
前端·javascript
生在地上要上天8 分钟前
从600行"状态地狱"到可维护策略模式:一次列表操作限制重构实践
前端