go - 当请求被取消或超时时如何从 http 处理程序返回
问题描述
我在做sse,重要的代码是:
var clientes=new(sync.Map)
type canalesStruct struct{
sender chan []byte
close chan bool
}
func (broker *brokerStruct) ServeHTTP(w http.ResponseWriter, r *http.Request) {
flusher, ok := w.(http.Flusher)
if !ok {
http.Error(w, "Streaming unsupported!", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
var ID string
//Get the ID somehow
canales:=new(canalesStruct)
canales.sender=make(chan []byte)
canales.close=make(chan bool)
clientes.store(ID,canales)
notify := w.(http.CloseNotifier).CloseNotify()
defer func() {
clientes.Delete(ID)
}()
for {
select {
case <-notify:
return
case <-canales.close:
return
case data:= <-canales.sender:
fmt.Fprintf(w, "data: %s\n\n",data)
flusher.Flush()
}
}
}
func sendDataToChanelID(ID string,data []byte){
canalesRaw,_:=clientes.Load(ID)
canales,_:=canalRaw(*canalesStruct)
canales.sender <-data
}
所以我有两个问题:
- 如果在接收数据时连接断开,fmt.Fprintf 会继续无限等待还是会立即返回?
- 如果它立即返回没有问题,但如果它继续等待,我该如何包装“fmt.Fprintf”以便在超时超过时返回?
解决方案
根据时间返回不同值的一种简单方法是在通道上等待。
func F() int {
// channel to receive info
c := make(chan int)
// start timeout goroutine
go func() {
time.Sleep(TIMEOUT)
c <- -1
}()
// start work goroutine
go func() {
c <- GetValue()
}()
// receive value
x := <-c
// start goroutine to discard late value
go func() {
_ = <-c
}()
// return received value
return x
}
因此,这两个 goroutine 正在相互竞争。如果超时首先到达那里,则值为 -1。
推荐阅读
- python - Load and Save Dictionary and Class Instances Python Script
- webrtc - WebRTC 可以通过 Android USB 以太网连接工作吗?
- css - Flex wrap 反向断裂?
- javascript - 生成 id 并将它们推送到 Javascript 中的数组中?
- verilog - Verilog 如何使用时钟逐位更改线路?
- c++ - 根据 R 与 rcpp 中的索引选择向量
- ios - 回调 URL 未调用 completionHandler
- vb.net - 使用 webclient 类提取特定链接
- html - 无法显示全屏图像背景
- azure - 在 DownloadBuildArtifact 任务中找不到下载的工件