ListenAndServe:它是否同时允许多个连接?

时间:2018-01-11 23:43:38

标签: go

我使用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...
  • 只有一个正在处理,第二个没有被调用。一旦返回第一个(15秒后),第二个开始。
  • 为什么?我希望它们能够并行处理......
  • 这是交易破坏者,这意味着客户无法在同一时间访问同一页面。

我如何回复客户端并稍后处理? 在处理程序中添加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连接并使用先前连接的行为。

1 个答案:

答案 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阻止您看到结果。