gout icon indicating copy to clipboard operation
gout copied to clipboard

是否支持event stream

Open b0123456789 opened this issue 2 years ago • 8 comments

b0123456789 avatar May 17 '22 04:05 b0123456789

怎么理解event stream, 可有具体的例子?

guonaihong avatar May 17 '22 06:05 guonaihong

e

试了一下,设置超时,可以抓取一条

b0123456789 avatar May 17 '22 14:05 b0123456789

https://github.com/r3labs/sse 这个库可以持续接受数据,不过我要只一条,也算够了

b0123456789 avatar May 17 '22 14:05 b0123456789

https://github.com/r3labs/sse 这个库可以持续接受数据,不过我要只一条,也算够了

扫了下源代码, 明白你的意思了, 利用http chunked(分块传输编码) 模拟流式消息推送. 以前在websocket没出来之前用得挺多. 现在一般直接用websocket推送消息.

guonaihong avatar May 17 '22 14:05 guonaihong

@guonaihong 大佬,chatgpt目前使用的就是sse, 现有的gout代码在Debug请求时可正常输出流式消息。但如果加上bindbody时就会报503错误。急用的情况下,debug日志消息该如何输出到变量里呢? image

Baiyuetribe avatar Dec 07 '22 17:12 Baiyuetribe

细看了文档,已解决, save to writer方法

Baiyuetribe avatar Dec 08 '22 03:12 Baiyuetribe

FsChat、OpenAI等都使用SSE协议(Server-Sent Events)来依次输出结果,因为大语言模型回复的都很慢,一般前端都使用的EventSource来实现打字效果。

可以使用下面方法来读取


func sse(ctx context.Context, url string, req any, callback func(line string)) error {

	response, err := gout.New().
		SetHeader(gout.H{
			"Accept": "text/event-stream",
		}).
		WithContext(ctx).
		POST(url).
		SetJSON(req).
		Response()

	if err != nil {
		return err
	} else if response.StatusCode != http.StatusOK || !strings.Contains(response.Header.Get("Content-Type"), "text/event-stream") {
		return fmt.Errorf("invalid status code: %d, content-type: %s", response.StatusCode, response.Header.Get("Content-Type"))
	}

	defer response.Body.Close()

	buf := bufio.NewReader(response.Body)
	for {
		line, err := buf.ReadString('\n')
		if err != nil && err != io.EOF {
			return err
		}
		callback(line)
		if err == io.EOF {
			break
		}
	}

	return nil
}


go-mixed avatar Feb 21 '24 13:02 go-mixed

@go-mixed 赞,我这个版本实现下sse的api。

guonaihong avatar Feb 21 '24 14:02 guonaihong