如何支持流式返回响应数据?(打字机效果) · Issue #6 · riba2534/openai

您所在的位置:网站首页 打字机效果ppt 如何支持流式返回响应数据?(打字机效果) · Issue #6 · riba2534/openai

如何支持流式返回响应数据?(打字机效果) · Issue #6 · riba2534/openai

2023-06-04 03:49| 来源: 网络整理| 查看: 265

我使用作者的反向代理,可以顺利访问openai的接口,但却不能流式返回(打字机效果)。 我做了个测试,本地起来这个服务,在浏览器调用了test接口,是可以实现流式返回的。 但如果把服务部署到腾讯云函数后,使用提供的公网ip调用test接口,则就是一次性返回response。 不确定是服务器设置问题?(但翻遍了服务器设置,也没有看见相关设置,正在提工单。。)还是代码问题? 下图是本地服务,可以看到response header里显示了Transfer-Encoding: chunked 图片 下图是部署到腾讯云函数后,response header里没有显示Transfer-Encoding: chunked 图片 求解决怎么搞?代码如下:

package main import ( "fmt" "log" "net" "net/http" "net/http/httputil" "net/url" "time" ) func main() { version := "1.0.2" targetUrl := "https://api.openai.com/" // 目标域名和端口 target, err := url.Parse(targetUrl) if err != nil { log.Fatal(err) } // 创建反向代理 proxy := httputil.NewSingleHostReverseProxy(target) // 设置输出缓冲区的刷新时间间隔 proxy.FlushInterval = 1 * time.Second // 修改请求头,将Host设置为目标域名 proxy.Director = func(req *http.Request) { req.Host = target.Host req.URL.Scheme = target.Scheme req.URL.Host = target.Host } // 设置超时时间 timeout := time.Duration(1 * time.Minute) proxy.Transport = &http.Transport{ Proxy: http.ProxyFromEnvironment, DialContext: (&net.Dialer{Timeout: timeout}).DialContext, MaxIdleConns: 100, IdleConnTimeout: 90 * time.Second, TLSHandshakeTimeout: 10 * time.Second, ExpectContinueTimeout: 1 * time.Second, } // 打印HTTP请求和响应的日志 proxy.ModifyResponse = func(resp *http.Response) error { // 打印HTTP响应的日志 responseDump, err := httputil.DumpResponse(resp, true) if err != nil { log.Printf("Failed to dump response: %v\n", err) } else { log.Printf("%s Response: \n%s\n", time.Now().Format("2006-01-02 15:04:05"), string(responseDump)) } return nil } // 设置日志前缀和输出位置 log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile) // 启动HTTP服务器 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { // 设置 Content-Type 和 Transfer-Encoding w.Header().Set("Content-Type", "text/plain") w.Header().Set("Transfer-Encoding", "chunked") // 将http.ResponseWriter转换为http.Flusher接口 flusher, ok := w.(http.Flusher) if !ok { http.Error(w, "Streaming unsupported!", http.StatusInternalServerError) log.Printf("Streaming unsupported!") return } else { log.Printf("Streaming supported!") } // 打印HTTP请求日志 requestDump, err := httputil.DumpRequest(r, true) if err != nil { log.Printf("Failed to dump request: \n%v\n", err) } else { log.Printf("proxy version: %s\n%s Request: %s\n", version, time.Now().Format("2006-01-02 15:04:05"), string(requestDump)) } // 反向代理转发 proxy.ServeHTTP(w, r) // 在每个数据块发送完毕后刷新响应缓冲区 flusher.Flush() }) http.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) { // 设置响应头 w.Header().Set("Content-Type", "text/event-stream") w.Header().Set("Cache-Control", "no-cache") // 设置Transfer-Encoding字段为"chunked" w.Header().Set("Transfer-Encoding", "chunked") w.WriteHeader(http.StatusOK) // 写入响应头 // 发送初始化事件 fmt.Fprint(w, "event: connect\n") fmt.Fprint(w, ": server connected\n\n") w.(http.Flusher).Flush() // 发送数据 for i := 0; i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3