我使用gorilla/mux
创建了一个小型Web服务器。
我在他们的Github页面的README文件末尾拿了一个小例子。
r := mux.NewRouter()
r.HandleFunc("/", listUrlsHandler)
r.HandleFunc("/foo", fooHandler)
http.Handle("/", r)
err := http.ListenAndServe(":9090", nil) // set listen port
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
为了模拟长处理,我在回调函数中添加了一个计时器。
func fooHandler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
fmt.Fprintln(w, "foo is downloading...")
log.Println("foo is downloading...")
time.Sleep(15*time.Second)
}
我同时运行2x /foo
:
2018/01/12 09:15:03 foo is downloading...
2018/01/12 09:15:18 foo is downloading...
我如何回复客户端并稍后处理? 在处理程序中添加goroutine?
func fooHandler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
fmt.Fprintln(w, "foo is downloading...")
log.Println("foo is downloading...")
go time.Sleep(15*time.Second) // HERE <------------
// go myCustomFunc() // HERE <------------
}
我知道它是如何工作的,但显然我完全错了。
我以为路由器在每次通话时都创建了goroutine
。
你能告诉我做什么的最佳做法吗?
我发现使用tcp dump的问题:
第二个请求打开一个150分钟后关闭的TCP连接(来自客户端的FIN)。然后第二个请求由第一个请求完成后第一个请求打开的第一个TCP连接处理。
可能是Firefox关闭TCP连接并使用先前连接的行为。
答案 0 :(得分:1)
如果您向处理程序添加日志调用,则可以查看何时处理响应:
func downloadFileHandler(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, "%s is downloading...\n", vars["namefile"])
log.Printf("%s is downloading...\n", vars["namefile"])
time.Sleep(15*time.Second)
}
例如:
2018/01/12 10:52:42 foo is downloading...
2018/01/12 10:52:44 bar is downloading...
由于Gorilla Mux使用Go的基础go例程,两个调用正在同步处理,但是15秒time.Sleep
阻止您看到结果。