登录
首页 >  Golang >  Go教程

为什么 Gin 的 ctx.Stream 在启用压缩中间件后无法实时输出结果?

时间:2024-11-17 21:48:34 498浏览 收藏

在IT行业这个发展更新速度很快的行业,只有不停止的学习,才不会被行业所淘汰。如果你是Golang学习者,那么本文《为什么 Gin 的 ctx.Stream 在启用压缩中间件后无法实时输出结果?》就很适合你!本篇内容主要包括##content_title##,希望对大家的知识积累有所帮助,助力实战开发!

为什么 Gin 的 ctx.Stream 在启用压缩中间件后无法实时输出结果?

gin 的 ctx.stream 为什么在方法执行结束后才输出结果?

问题:

gin 的 ctx.stream 无法按预期地实时输出,而是在控制器方法执行完成后才一次性输出结果。这是为什么?

解答:

当 gin 启用了压缩输出中间件(例如 brotli.brotli)后,ctx.stream 将不起作用。这是因为:

  • accept-encoding:如果请求头中未指定 "accept-encoding: br",则 gin 不会对响应内容进行压缩。
  • connection:如果请求头中指定 "connection: upgrade",则 gin 会认为这是 websocket 请求,从而跳过压缩。
  • content-type:如果请求头中指定 "content-type: text/event-stream",则 gin 将按 sse 协议处理响应,同样跳过压缩。

此时,可以在请求头中明确指定 "content-type: text/event-stream" 以避免压缩,从而让 ctx.stream 按预期地实时输出。

参考 gin 源代码中 shouldcompress 方法的实现:

func shouldCompress(req *http.Request, options *Options) bool {
    if !strings.Contains(req.Header.Get("Accept-Encoding"), "br") ||
        strings.Contains(req.Header.Get("Connection"), "Upgrade") ||
        strings.Contains(req.Header.Get("Content-Type"), "text/event-stream") {

        return false
    }

    extension := filepath.Ext(req.URL.Path)
    if len(extension) < 4 { // fast path
        return true
    }

    if skip := containsString(options.SkipExtensions, extension); skip {
        return false
    } else {
        return true
    }
}

到这里,我们也就讲完了《为什么 Gin 的 ctx.Stream 在启用压缩中间件后无法实时输出结果?》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于的知识点!

相关阅读
更多>
最新阅读
更多>
课程推荐
更多>