重点
先说一个踩过的坑:如果要使用 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 流式响应,使得能够在前端展示一个字一个字蹦出来的效果。