服务端实现SSE与客户端调用示例

随着Ai大模型的兴起,越来越多的应用需要集成和利用Ai的能力。
但是,大模型在推理的时候往往需要一些时间,结果也不是一次性返回的,这个时候我们就需要用到服务端向客户端推送消息,也就是SSE.

SSE(Server-Sent Events,服务器发送事件)是一种网络通信技术,允许服务器向客户端推送信息,而不需要客户端显式地请求。这是一种实现服务器到客户端单向实时通信的方式。SSE 是 HTML5 规范的一部分,并且许多现代浏览器都支持这一技术。

SSE 的主要特点:

  1. 单项通信:数据只能从服务器推送到客户端,而不是双向的。
  2. 基于HTTP:SSE 使用普通的 HTTP 连接,与 WebSocket 不同,后者需要更复杂的握手过程。
  3. 持久连接:一旦客户端与服务器建立连接,该连接会保持开放,直到客户端或服务器关闭它。
  4. 文本数据:SSE 仅支持文本数据格式,尽管可以发送 JSON 格式的字符串来传输结构化数据。
  5. 自动重连:如果连接断开,浏览器会尝试重新连接服务器。
  6. 事件驱动:服务器可以发送不同类型的事件,客户端可以监听这些事件。

SSE 的工作流程:

  1. 建立连接:客户端发送一个普通的 HTTP 请求到服务器,并在请求头中指定 Accept: text/event-stream,表示客户端希望使用 SSE。
  2. 服务器响应:服务器以 text/event-stream 格式响应,保持连接开启。
  3. 发送事件:服务器可以通过这个开启的连接发送事件,每个事件由一个或多个以 \n\n 分隔的消息组成。
  4. 客户端处理:客户端有一个 EventSource 对象,用于处理从服务器接收到的消息。

SSE 的应用场景:

  • 实时通知:例如,社交网络、邮件服务中的新消息提醒。
  • 实时数据更新:股票价格、天气预报等实时数据的展示。
  • 日志监控:实时传输服务器日志到客户端,便于监控。

SSE 相对于其他实时通信技术的优势在于它的简单性和易用性,不需要复杂的配置和额外的协议支持。然而,它也有局限性,比如它不支持CORS(跨源资源共享),数据传输是单向的,且仅支持文本数据。

由于这些特点,SSE 特别适合于那些需要从服务器到客户端单向、实时的数据流的场景。

代码示例

下面演示的是在cool-admin如何实现:

服务端

import { CoolController, BaseController } from "@cool-midway/core";
import { Get, Inject } from "@midwayjs/core";
import { Context } from "koa";
import { PluginService } from "../../../plugin/service/info";
import { PassThrough } from "stream";

/**
 * 事件流 服务端主动推送
 */
@CoolController()
export class OpenDemoSSEController extends BaseController {
    @Inject()
    ctx: Context;

    @Inject()
    pluginService: PluginService;

    @Get("/call", { summary: "事件流 服务端主动推送" })
    async call() {
        // 设置响应头
        this.ctx.set("Content-Type", "text/event-stream");
        this.ctx.set("Cache-Control", "no-cache");
        this.ctx.set("Connection", "keep-alive");

        const stream = new PassThrough();

        // 发送数据
        const send = (data: any) => {
            stream.write(`data: ${JSON.stringify(data)}\n\n`);
        };

        // 获取插件实例
        const instance = await this.pluginService.getInstance("ollama");
        // 调用chat
        const messages = [
            { role: "system", content: "你叫小酷,是个编程助手" },
            { role: "user", content: "用js写个Hello World" }
        ];
        instance.chat(messages, { stream: true }, (res) => {
            send(res);
            if (res.isEnd) {
                this.ctx.res.end();
            }
        });

        this.ctx.status = 200;
        this.ctx.body = stream;
    }
}

客户端

const axios = require("axios");

const url = "http://127.0.0.1:8001/open/demo/sse/call";

const eventSource = axios.get(url, {
    responseType: "stream"
});

eventSource.then((response) => {
    // 收到消息
    response.data.on("data", (event) => {
        console.log("Message received:", event.toString());
    });
    // 发送结束
    response.data.on("end", () => {
        console.log("Connection closed");
    });
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值