作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!


具体的思路是这样:通过 RequestCtx 的 Conn() 方法,获得 tcp 套接字。然后直接在 tcp 套接字上 Write 流式内容就行。

上代码:

package main

import (
"bufio"
"bytes"
"fmt"
"io"
syslog "log"
"net"
"os"
"strconv"
"time" "github.com/valyala/bytebufferpool"
"github.com/valyala/fasthttp"
) func FasthttpHandler(ctx *fasthttp.RequestCtx) {
ctx.HijackSetNoResponse(true) // 不使用 fasthttp 框架的输出
ctx.Hijack(func(c net.Conn) { // 这里会 go 出来一个协程执行 hijack 回调函数
log.Println("do nothing")
})
//
buf := bytebufferpool.Get()
defer bytebufferpool.Put(buf)
buf.Reset()
buf.B = append(buf.B, "HTTP/1.1 200 OK\r\n"+
"Server: fasthttp\r\n"+
"Date: Thu, 26 Oct 2023 01:09:23 GMT\r\n"+
"Content-Type: text/plain\r\n"+
"Cache-Control: no-cache, no-store, must-revalidate\r\n"+
"Transfer-Encoding: chunked\r\n"+
"\r\n"...)
conn := ctx.Conn()
_, _ = conn.Write(buf.B) // 写 http 头
//
for i := 0; i < 9; i++ {
_, _ = conn.Write([]byte(fmt.Sprintf("%x\r\n%d \r\n", 1, i)))
time.Sleep(1 * time.Second)
}
// 写入结束信息
_, _ = conn.Write([]byte("0\r\n\r\n")
} func main() {
syslog.SetFlags(syslog.Lshortfile | syslog.LstdFlags)
server := &fasthttp.Server{
Handler: FasthttpHandler,
}
syslog.Fatalln(server.ListenAndServe(":8089"))
}

通过上述的方式虽然可以实现流式输出,但实际测试发现性能很差。

性能差的原因是每次请求都会 go 出来协程去执行 hijack 函数。

为此我改了一个版本,只要不设置 hijack 函数就不会产生协程去调用:

在 go.mod 中加上这样一句:

replace (
github.com/valyala/fasthttp => github.com/ahfuzhang/compress v1.49.2
)

然后注释掉设置 hijack 的那几行:

    ctx.HijackSetNoResponse(true)
//ctx.Hijack(func(c net.Conn) {
// log.Println("do nothing")
//})

希望对大家有用,have fun

fasthttp 中如何使用`Transfer-Encoding: chunked` 方式的流式内容输出的更多相关文章

  1. HTTP协议扫盲(八 )响应报文之 Transfer-Encoding=chunked方式

    一.什么是chunked编码? 分块传输编码(Chunked transfer encoding)是只在HTTP协议1.1版本(HTTP/1.1)中提供的一种数据传送机制.以往HTTP的应答中数据是整 ...

  2. android中解析文件的三种方式

    android中解析文件的三种方式     好久没有动手写点东西了,最近在研究android的相关技术,现在就android中解析文件的三种方式做以下总结.其主要有:SAX(Simple API fo ...

  3. Struts中的数据处理的三种方式

    Struts中的数据处理的三种方式: public class DataAction extends ActionSupport{ @Override public String execute() ...

  4. spring 整合 mybatis 中数据源的几种配置方式

    因为spring 整合mybatis的过程中, 有好几种整合方式,尤其是数据源那块,经常看到不一样的配置方式,总感觉有点乱,所以今天有空总结下. 一.采用org.mybatis.spring.mapp ...

  5. Qt中三种解析xml的方式

    在下面的随笔中,我会根据xml的结构,给出Qt中解析这个xml的三种方式的代码.虽然,这个代码时通过调用Qt的函数实现的,但是,很多开源的C++解析xml的库,甚至很多其他语言解析xml的库,都和下面 ...

  6. Struts2中的数据处理的三种方式对比(Action中三种作用域request,session,application对象)

    1:在Action中如何获得作用域(request,session,application)对象: 取得Map(键值对映射集)类型的requet,session,application; 对数据操作的 ...

  7. C#中Post请求的两种方式发送参数链和Body的

    POST请求 有两种方式 一种是组装key=value这种参数对的方式 一种是直接把一个字符串发送过去 作为body的方式 我们在postman中可以看到 sfdsafd sdfsdfds publi ...

  8. Spring中依赖注入的四种方式

    在Spring容器中为一个bean配置依赖注入有三种方式: · 使用属性的setter方法注入  这是最常用的方式: · 使用构造器注入: · 使用Filed注入(用于注解方式). 使用属性的sett ...

  9. JavaWeb应用中初始化Log4j的两种方式

    本文主要介绍了普通JavaWeb应用(基于Tomcat)中初始化Log4j的两种方式: 1.通过增加 InitServlet ,设置令其自启动来初始化 Log4j . 2.通过监听器 ServletC ...

  10. linux内核分析作业4:使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用

    系统调用:库函数封装了系统调用,通过库函数和系统调用打交道 用户态:低级别执行状态,代码的掌控范围会受到限制. 内核态:高执行级别,代码可移植性特权指令,访问任意物理地址 为什么划分级别:如果全部特权 ...

随机推荐

  1. 应用开发专家一席谈:开发低代码,上手低门槛,AppCube使能Citizen Developer,人人都是开发者

    摘要:让不确定因子变为确定性因子,把复杂留给平台,简单留给开发者,是软件开发效率改进一直努力的方向,也是低代码理念的来源. 本文分享自华为云社区<应用开发专家一席谈:开发低代码,上手低门槛,Ap ...

  2. 如何在iPhone设备中查看崩溃日志

    ​ ​如何在iPhone设备中查看崩溃日志 目录 如何在iPhone设备中查看崩溃日志 摘要 引言 导致iPhone设备崩溃的主要原因是什么? 使用克魔助手查看iPhone设备中的崩溃日志 奔溃日志分 ...

  3. Solon Web 开发,十、签权

    Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...

  4. Jenkins Pipeline 流水线 - 拉代码(SVN) + Maven 编译打包

    Jenkins Pipeline 流水线 步骤 拉取SVN代码 -> Maven 构建 -> Docker 编译 -> 发布至阿里云仓库 -> K8S 更新 Jenkins插件 ...

  5. CNCF大使预测:2024年云原生面临倦怠、离职及云成本精简

    本文由 CNCF 大使 Eric D. Schabell 撰写,预测2024年云原生领域最可能发生的3大变化,并与其对云原生可观测性领域的见解结合. 关注云原生倦怠 毫无疑问,在 2023 年中云原生 ...

  6. OpenShift 与 OpenStack:让云变得更简单

    OpenShift 与 OpenStack 都是在 2010.2011 年左右创建的,用于构建可扩展云平台的开源技术,两者都用于在混合云环境中构建可扩展系统.从历史来看,OpenStack 的存在时间 ...

  7. ME2N增强

    一.ME2N增加字段 二.结构中添加扩展字段 附加结构中添加同名这些字段时会报错,原因是MEREP_OUTTAB_DOWNPAY等结构已存在该字段,导致冲突 三.添加逻辑代码 包含文件LMEREPI0 ...

  8. AtCoder Beginner Contest 211 (C ~ E) 个人题解

    比赛链接:Here A.B题跳过 C - chokudai 题意: 给出一个字符串,问有多少个字串能构成 chokudai 这道题算是一个简单DP,只要计算某个位置对构成 chokudai 的贡献值即 ...

  9. 【转载】内存基本概念-伙伴(Buddy)算法

    简介 ​ 在Linux系统中,内存的分配与回收速率直接影响系统的存取效率.当内核频繁请求和释放不同大小的一组连续页框时,会导致许多外部空闲碎片,造成空间的浪费.使用伙伴算法可以有效地缓解该问题.伙伴关 ...

  10. java 服务 JVM 参数设置配置

    本文为博主原创,转载请注明出处: 常用JVM 配置参数: -Xmx:表示java虚拟机堆区内存可被分配的最大上限,通常为操作系统可用内存的1/4大小. -Xms:表示java虚拟机堆区内存初始内存分配 ...