如何使用 Server-Sent Events 在 Yii2 中构建实时 Web 应用程序

阅读时长 6 分钟读完

随着 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 对象来接收服务器端推送的消息:

然后,在服务器端我们需要准备一个 SSE 的响应:

-- -------------------- ---- -------
--- -----------------

--------- - --------------------
----------------- - ---------------------
--------------------------------------- ---------------------
---------------------------------------- ------------

----- ------ -
    -- ---------
    -------- - --------------------
    
    -- -- --- --
    ---- ------- -----------
    ---- ------ - - --------------------- - -------
    --------
    
    -- -- -- ------
    ----------
-

在 SSE 的响应中,我们先设置响应格式为 text/event-stream,然后进行长轮询,每隔 10 秒钟查询一次城市的天气信息并将其封装成一个 SSE 事件发送到浏览器端。

对于 SSE 事件,我们可以自定义事件类型,这里使用了 weather 作为事件类型,服务器端发送的消息使用 JSON 格式进行编码。

需要注意的是,在发送 SSE 响应时需要设置 Cache-Control 头为 no-cache,以避免浏览器缓存问题。同时,在向客户端发送 SSE 的时候,我们需要使用 flush() 函数强制将数据发送给客户端,否则客户端可能会等很久才能接收到数据。

除了手动编写 SSE 响应对象外,Yii2 中也提供了两个方便的扩展包装类库:yiisoft/yii2-sseyiisoft/yii2-sseclient.

yiisoft/yii2-sse 包包含了一个名为 SSEController 的控制器类,继承了 Yii2 中的 yii\web\Controller,通过它可以方便地创建 SSE 响应。使用方法如下:

-- -------------------- ---- -------
--- --------------
--- -------------------

----- ----------------- ------- ----------
-
    ------ -------- ---------
    -
        ------ -
            --------- -- -
                ------- -- --------------------
                ------ -- ---------- -
                    -- ---------
                    -------- - --------------------
                    ------ --- -------
                        ------ -- ----------
                        ------ -- ---------
                    ---
                --
            --
        --
    -
-

这里我们通过 yii/sse/Event 类来封装 SSE 事件,然后在 yii\sse\SSEAction 中返回这个事件即可。使用这种方式,Yii2 会在构造响应时自动加入 Cache-ControlContent-Type 等头信息。

yiisoft/yii2-sseclient 包则提供了一个 SSE 客户端类,方便我们在测试时模拟 SSE 服务器。使用方法如下:

这里我们创建了一个 SSE 客户端对象,并向其传递 SSE 服务器的 URL。然后通过 $client->on() 方法来注册回调函数,接收 SSE 服务器推送的事件。最后通过 $client->start() 方法启动 SSE 客户端,开始接收事件。

总结

本文介绍了如何使用 Yii2 中的 yii\web\Response 类和两个包装类库 yiisoft/yii2-sseyiisoft/yii2-sseclient 来实现 Server-Sent Events 协议,构建实时 Web 应用程序。Server-Sent Events 具有轻量级、无需双向通信和兼容性良好等特点,在一些不需要高速传输数据的场景下是一种非常不错的解决方案。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/651ea2fa95b1f8cacd650912

纠错
反馈