栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

为什么Golang http.ResponseWriter执行被延迟?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

为什么Golang http.ResponseWriter执行被延迟?

HTTP协议的原始概念是一个简单的请求-
响应服务器-客户端计算模型。没有流或“连续”客户端更新支持。总是(总是)首先联系服务器的客户端需要它的某种信息。

同样,由于大多数Web服务器都会缓存响应,直到响应完全就绪(或达到一定的限制,通常是缓冲区大小)为止,因此您写入(发送)到客户端的数据将不会立即传输。

为了避免这种“局限性”,已经开发出了几种技术,以便服务器能够通知客户端有关更改或进度的信息,例如HTTP Long轮询,HTTP流,HTTP / 2
Server
Push或Websockets。

因此,要实现您想要的目标,您必须绕过HTTP协议的原始“边界”。

如果要定期发送数据或将数据流传输到客户端,则必须将此信息告知服务器。最简单的方法是检查

http.ResponseWriter
传递给您的
http.Flusher
接口是否实现了接口(使用类型断言),如果接口实现了,则调用其
Flusher.Flush()
方法会将所有缓冲的数据发送到客户端。

使用

http.Flusher
仅是解决方案的一半。由于这是HTTP协议的非标准用法,因此通常也需要客户端支持才能正确处理。

首先,您必须通过设置

ContentType=text/event-stream
响应头来让客户端了解响应的“流”性质。

接下来,为避免客户端缓存响应,请务必同时设置

Cache-Control=no-cache

最后,要让客户端知道您可能不会以单个单元(而是以定期更新或流的形式)发送响应,并且让客户端保持连接活动并等待更多数据,请设置

Connection=keep-alive
响应头。

将响应标头设置为上述值后,就可以开始漫长的工作,并且每当您要向客户端更新进度时,都可以编写一些数据并调用

Flusher.Flush()

让我们看一个简单的示例,它“正确”地执行所有操作:

func longHandler(w http.ResponseWriter, r *http.Request) {    flusher, ok := w.(http.Flusher)    if !ok {        http.Error(w, "Server does not support Flusher!", http.StatusInternalServerError)        return    }    w.Header().Set("Content-Type", "text/event-stream")    w.Header().Set("Cache-Control", "no-cache")    w.Header().Set("Connection", "keep-alive")    start := time.Now()    for rows, max := 0, 50*1000; rows < max; {        time.Sleep(time.Second) // Simulating work...        rows += 10 * 1000        fmt.Fprintf(w, "Rows done: %d (%d%%), elapsed: %vn", rows, rows*100/max, time.Since(start).Truncate(time.Millisecond))        flusher.Flush()    }}func main() {    http.HandleFunc("/long", longHandler)    panic(http.ListenAndServe("localhost:8080", nil))}

现在,如果您

http://localhost:8080/long
在浏览器中打开,您将看到输出每秒“增长”:

Rows done: 10000 (20%), elapsed: 1sRows done: 20000 (40%), elapsed: 2sRows done: 30000 (60%), elapsed: 3sRows done: 40000 (80%), elapsed: 4.001sRows done: 50000 (100%), elapsed: 5.001s

另请注意,使用SSE时,应将更新“打包”到SSE框架中,即应以

"data:"
前缀开头,并以2个换行符结束每个框架
"nn"

“文学”和进一步阅读/教程

在Wikipedia上了解有关服务器发送事件的更多信息。

请参阅Golang HTML5 SSE示例。

请参阅带有客户端代码的Golang SSE服务器示例。

请参阅w3school.com关于服务器发送事件-
单向消息传递的资料。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/484145.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号