重点

先说一个踩过的坑:如果要使用 SSE 流式响应,那么在 Nginx 里不要开启该接口的 Gzip !!!
因为开启 Gzip 后会导致数据达到一定大小才会被压缩然后返回给前端,导致前端不能实时获得数据,就无法形成流式的文本效果。

例子

举个在 ASP.NET Core 中实现 SSE 流式响应的简单例子。

[HttpGet]
public async Task<IActionResult> SseExample()
{
    // 请求头
    Response.Headers.Add("Content-Type", "text/event-stream");
    Response.Headers.Add("Cache-Control", "no-cache");
    Response.Headers.Add("Connection", "keep-alive");

    // 假设不断得到新数据
    for (int i = 0; i < 10; i++)
    {
        // 每个数据参照 SSE 返回数据格式进行组装
        var content = "event: message\n"
            + "data: {\"color\":\"66ccff\"}\n\n";

        // 立刻写入响应
        await Response.WriteAsync(content);
        await Response.Body.FlushAsync();
    }

    // 结束
    return new EmptyResult();
}

测试的时候可以从控制台的网络详情里看到本次响应的数据流:

备注

我目前主要是希望搭一套向量知识库(选了MaxKB),查询出知识库中的已知信息然后利用大模型分析回答。因为需要对知识库的输入做处理(比如增加关键字,过滤某些信息,相同问题查缓存等),直接暴露知识库 API 风险较高,可能 token 都被人用来问大模型其他问题了,因此需要做一层处理和转发。而当前后端是基于 ASP.NET Core 的,所以需要在 ASP.NET Core 里实现 SSE 流式响应,使得能够在前端展示一个字一个字蹦出来的效果。

如果觉得我的文章对你有用,请随意赞赏