随着 Web 技术的不断发展,越来越多的应用程序需要实时展示数据,实时通信成为了不可避免的需求。而在前端实现实时通信的方式有很多,其中 Server-Sent Events (SSE) 是一种轻量级的解决方案。本文将介绍如何使用 SSE 在 Yii2 中构建实时 Web 应用程序。
什么是 Server-Sent Events
Server-Sent Events 是一种浏览器与服务器之间的单向通信方式,通过这种方式可以将服务器端的数据实时推送到浏览器端。相较于 WebSocket,SSE 更为简单轻量,适用于一些不需要双向通信的场景。
SSE 的优点在于它具有以下特点:
- 基于 HTTP 的标准协议,兼容性良好;
- 支持自定义事件类型;
- 支持无限制的长连接,可以持续不断地推送数据。
在 Yii2 中,我们可以使用 yii\web\Response 实现 SSE 协议,同时也可以使用一些包装类库简化操作。
Yii2 中使用 SSE 实现实时数据推送
假设我们有一个需求,即用户在某个界面上选择了一个城市,我们需要实时显示这个城市的天气信息。这时候我们可以使用 SSE 来实时推送查询到的天气信息。
首先,我们需要在前端页面创建一个 EventSource 对象来接收服务器端推送的消息:
var source = new EventSource("/weather.php?city=" + city); source.onmessage = function(event) { console.log(event.data); // 处理服务器端推送的消息 }; source.onerror = function(event) { console.error("EventSource error:", event); };
然后,在服务器端我们需要准备一个 SSE 的响应:
-- -------------------- ---- ------- --- ----------------- --------- - -------------------- ----------------- - --------------------- --------------------------------------- --------------------- ---------------------------------------- ------------ ----- ------ - -- --------- -------- - -------------------- -- -- --- -- ---- ------- ----------- ---- ------ - - --------------------- - ------- -------- -- -- -- ------ ---------- -
在 SSE 的响应中,我们先设置响应格式为 text/event-stream
,然后进行长轮询,每隔 10 秒钟查询一次城市的天气信息并将其封装成一个 SSE 事件发送到浏览器端。
对于 SSE 事件,我们可以自定义事件类型,这里使用了 weather
作为事件类型,服务器端发送的消息使用 JSON 格式进行编码。
需要注意的是,在发送 SSE 响应时需要设置 Cache-Control
头为 no-cache
,以避免浏览器缓存问题。同时,在向客户端发送 SSE 的时候,我们需要使用 flush()
函数强制将数据发送给客户端,否则客户端可能会等很久才能接收到数据。
除了手动编写 SSE 响应对象外,Yii2 中也提供了两个方便的扩展包装类库:yiisoft/yii2-sse
和 yiisoft/yii2-sseclient
.
yiisoft/yii2-sse
包包含了一个名为 SSEController
的控制器类,继承了 Yii2 中的 yii\web\Controller
,通过它可以方便地创建 SSE 响应。使用方法如下:
-- -------------------- ---- ------- --- -------------- --- ------------------- ----- ----------------- ------- ---------- - ------ -------- --------- - ------ - --------- -- - ------- -- -------------------- ------ -- ---------- - -- --------- -------- - -------------------- ------ --- ------- ------ -- ---------- ------ -- --------- --- -- -- -- - -
这里我们通过 yii/sse/Event
类来封装 SSE 事件,然后在 yii\sse\SSEAction
中返回这个事件即可。使用这种方式,Yii2 会在构造响应时自动加入 Cache-Control
和 Content-Type
等头信息。
yiisoft/yii2-sseclient
包则提供了一个 SSE 客户端类,方便我们在测试时模拟 SSE 服务器。使用方法如下:
use yii\sseclient\SSEClient; $client = new SSEClient(['url' => 'http://example.com/weather']); $client->on('weather', function($event) { // 处理 SSE 事件 }); $client->start();
这里我们创建了一个 SSE 客户端对象,并向其传递 SSE 服务器的 URL。然后通过 $client->on()
方法来注册回调函数,接收 SSE 服务器推送的事件。最后通过 $client->start()
方法启动 SSE 客户端,开始接收事件。
总结
本文介绍了如何使用 Yii2 中的 yii\web\Response
类和两个包装类库 yiisoft/yii2-sse
和 yiisoft/yii2-sseclient
来实现 Server-Sent Events 协议,构建实时 Web 应用程序。Server-Sent Events 具有轻量级、无需双向通信和兼容性良好等特点,在一些不需要高速传输数据的场景下是一种非常不错的解决方案。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/651ea2fa95b1f8cacd650912