英文:
How golang stop handler function if connection is lost
问题
似乎即使连接丢失,处理程序函数仍然在运行。例如,如果我访问http://0.0.0.0:8000/home并突然关闭浏览器,屏幕将继续打印所有的数字。
package main
import (
"fmt"
"net/http"
"time"
)
func main() {
http.HandleFunc("/home", func(w http.ResponseWriter, r *http.Request) {
i := 0
for {
fmt.Println("i", i)
i++
time.Sleep(time.Microsecond * 15)
}
})
http.ListenAndServe(":8000", nil)
}
相关链接:https://stackoverflow.com/questions/53323110/how-golang-gin-stop-handler-function-immediately-if-connection-is-lost
英文:
It seems even if the connection is lost, the handler function is still running. For example, if I visit http://0.0.0.0:8000/home and close the browser suddenly, the screen will continue to print all the numbers.
package main
import (
"fmt"
"net/http"
"time"
)
func main() {
http.HandleFunc("/home", func(w http.ResponseWriter, r *http.Request) {
i := 0
for {
fmt.Println("i", i)
i++
time.Sleep(time.Microsecond * 15)
}
})
http.ListenAndServe(":8000", nil)
}
答案1
得分: 2
选项1:在断开连接时,使用断开连接的连接写入会返回错误。当fmt.Println返回错误时,退出循环。
func example(w http.ResponseWriter, r *http.Request) {
i := 0
for {
_, err := fmt.Println("i", i)
if err != nil {
return
}
i++
time.Sleep(time.Microsecond * 15)
}
}
选项2:服务器在断开连接时取消请求上下文。只要上下文未被取消,就循环执行。
func example(w http.ResponseWriter, r *http.Request) {
i := 0
c := r.Context()
for c.Err() == nil {
fmt.Println("i", i)
i++
time.Sleep(time.Microsecond * 15)
}
}
选项3:服务器在断开连接时取消请求上下文。循环等待上下文取消或计时器。在取消时退出。
func example(w http.ResponseWriter, r *http.Request) {
t := time.NewTicker(time.Microsecond * 15)
defer t.Stop()
done := r.Context().Done()
for {
select {
case <-done:
fmt.Println("Done!")
return
case t := <-t.C:
fmt.Println("Current time:", t)
}
}
}
选项3会更早地返回处理程序。选项1和2在处理程序返回之前始终等待sleep完成。
英文:
Option 1: Write on a disconnected connection returns an error. Break from the loop when fmt.Println returns an error.
func example(w http.ResponseWriter, r *http.Request) {
i := 0
for {
_, err := fmt.Println("i", i)
if err != nil {
return
}
i++
time.Sleep(time.Microsecond * 15)
}
}
Option 2: The server cancels the request context on disconnect. Loop while the context is not canceled.
func example(w http.ResponseWriter, r *http.Request) {
i := 0
c := r.Context()
for c.Err() == nil {
fmt.Println("i", i)
i++
time.Sleep(time.Microsecond * 15)
}
}
Option 3: The server cancels the request context on disconnect. Loop waiting for context cancelation or timer. Exit on cancelation.
func example(w http.ResponseWriter, r *http.Request) {
t := time.NewTicker(time.Microsecond * 15)
defer t.Stop()
done := r.Context().Done()
for {
for {
select {
case <-done:
fmt.Println("Done!")
return
case t := <-t.C:
fmt.Println("Current time: ", t)
}
}
}
}
The handler will return earlier with option 3.
Option 1 and 2 always wait for sleep to complete before handler returns.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论