Nginx SSE支持
CMS站点 以windows服务运行,并且使用nginx代理后,其他功能正常。但是重建文章出现问题。点击后滚动条不会动。API也没有执行。
重建文章代码:
使用的是 text/event-stream 简称SSE
C# 全选
public async Task ReBuildIndex()
{
var response = Response;
response.Headers.Append("Content-Type", "text/event-stream");
YESCMS.Search.DoManageIndex manageIndex = new Search.DoManageIndex();
await manageIndex.RebuildAllIndex(async (index, total) =>
{
var data = new
{
total = total,
index = index
};
string str = Newtonsoft.Json.JsonConvert.SerializeObject(data);
await response.WriteAsync($"data: {str} \r\r");
response.Body.Flush();
});
}代码部分
发布模式下Kestrel 对chunked encoding非常严格
- 数据块必须是\n\n结尾,且\n\n前面不能有空格
- response.Body.Flush() 必须使用异步 await response.Body.FlushAsync();
SSE推荐添加下面两行代码
C# 全选
Response.Headers.Append("Connection", "keep-alive");
Response.Headers.Append("Cache-Control", "no-cache");因此,改造后代码如下:
C# 全选
public async Task ReBuildIndex()
{
var response = Response;
response.Headers.Append("Content-Type", "text/event-stream");
response.Headers.Append("Cache-Control", "no-cache");
response.Headers.Append("Connection", "keep-alive");
try
{
YESCMS.Search.DoManageIndex manageIndex = new Search.DoManageIndex();
await manageIndex.RebuildAllIndex(async (index, total) =>
{
var data = new
{
total = total,
index = index
};
string str = Newtonsoft.Json.JsonConvert.SerializeObject(data);
await response.WriteAsync($"data: {str}\n\n");
await response.Body.FlushAsync();
});
}
catch (Exception ex)
{
Console.WriteLine(ex); // 或写日志
}
}如果项目中启用了压缩,也要处理一下
方式一:直接关闭压缩(先验证)
C# 全选
// 注释掉
// app.UseResponseCompression();方式二:只对 SSE 禁用压缩(推荐)
C# 全选
app.Use(async (context, next) =>
{
if (context.Request.Path.StartsWithSegments("/admin666"))
{
context.Response.Headers.Remove("Content-Encoding");
}
await next();
});Nginx配置
Markup 全选
location /admin666/ {
proxy_pass http://127.0.0.1:5000;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_buffering off; # ❗核心
proxy_cache off;
chunked_transfer_encoding on;
proxy_read_timeout 3600s; # ❗防止断流
proxy_send_timeout 3600s;
}
版权声明:本文为YES开发框架网发布内容,转载请附上原文出处连接
post 张国生


