客户端关闭连接时,Go http.ResponseWriter.Write 不返回错误

我编写了一个简单的 http HandleFunc,需要 2 秒来处理,然后我向服务器发送一个超时 1 秒的请求。我希望调用 ResponseWriter.Write 会返回一个错误,但它不会。请为我解释一下。


服务器代码:



import (

    "log"

    "net/http"

    "time"

)


func main() {

    log.SetFlags(log.Ltime | log.Lshortfile)


    handler := http.NewServeMux()

    handler.HandleFunc("/long-task",

        func(w http.ResponseWriter, r *http.Request) {

            go func() {

                <-r.Context().Done()

                log.Println("client closed or server responded")

            }()

            log.Println("handling long-task")

            time.Sleep(2 * time.Second)

            n, err := w.Write([]byte("my slow response"))

            if err != nil {

                log.Println("error when ResponseWriter Write: ", err)

            }

            log.Printf("responded to long-task. n: %v\n", n)

        })

    server := &http.Server{Addr: ":8008", Handler: handler}


    log.Println("listening on port ", server.Addr)

    err := server.ListenAndServe()

    if err != nil {

        log.Fatal(err)

    }

}

客户端代码:


package main


import (

    "io/ioutil"

    "log"

    "net/http"

    "time"

)


func main() {

    client := http.Client{Timeout: 1 * time.Second}

    r, _ := http.NewRequest("GET", "http://127.0.0.1:8008/long-task", nil)

    w, err := client.Do(r)

    if err != nil {

        log.Fatal(err)

    }

    defer w.Body.Close()

    body, err := ioutil.ReadAll(w.Body)

    if err != nil {

        log.Fatal(err)

    }

    log.Printf("response: %s\n", body)

}

服务器输出:


10:50:58 http_server.go:28: listening on port  :8008

10:51:01 http_server.go:19: handling long-task

10:51:02 http_server.go:17: client closed or server responded

10:51:03 http_server.go:25: responded to long-task. n: 16

客户端输出:


2020/05/27 10:51:02 Get "http://127.0.0.1:8008/long-task": context deadline exceeded (Client.Timeout exceeded while awaiting headers)



沧海一幻觉
浏览 247回答 1
1回答

largeQ

写入的数据太少,ResponseWriter 没有将缓冲的数据发送给客户端。&nbsp; &nbsp; handler.HandleFunc("/long-task", func(w http.ResponseWriter, r *http.Request) {&nbsp; &nbsp; &nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <-r.Context().Done()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.Println("client closed or server responded")&nbsp; &nbsp; &nbsp; &nbsp; }()&nbsp; &nbsp; &nbsp; &nbsp; log.Println("handling long-task")&nbsp; &nbsp; &nbsp; &nbsp; time.Sleep(2 * time.Second)&nbsp; &nbsp; &nbsp; &nbsp; for i := 0; i < 520; i++ {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _, err := w.Write([]byte("my slow response"))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.Println("error when ResponseWriter Write: ", err, i)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // log.Printf("responded to long-task. n: %v\n", n)&nbsp; &nbsp; })输出:13:53:19 01.go:30: listening on port&nbsp; :800813:53:22 01.go:18: handling long-task13:53:23 01.go:16: client closed or server responded13:53:24 01.go:23: error when ResponseWriter Write:&nbsp; write tcp 127.0.0.1:8008->127.0.0.1:57098: write: broken pipe 51213:53:24 01.go:23: error when ResponseWriter Write:&nbsp; write tcp 127.0.0.1:8008->127.0.0.1:57098: write: broken pipe 51313:53:24 01.go:23: error when ResponseWriter Write:&nbsp; write tcp 127.0.0.1:8008->127.0.0.1:57098: write: broken pipe 51413:53:24 01.go:23: error when ResponseWriter Write:&nbsp; write tcp 127.0.0.1:8008->127.0.0.1:57098: write: broken pipe 51513:53:24 01.go:23: error when ResponseWriter Write:&nbsp; write tcp 127.0.0.1:8008->127.0.0.1:57098: write: broken pipe 51613:53:24 01.go:23: error when ResponseWriter Write:&nbsp; write tcp 127.0.0.1:8008->127.0.0.1:57098: write: broken pipe 51713:53:24 01.go:23: error when ResponseWriter Write:&nbsp; write tcp 127.0.0.1:8008->127.0.0.1:57098: write: broken pipe 51813:53:24 01.go:23: error when ResponseWriter Write:&nbsp; write tcp 127.0.0.1:8008->127.0.0.1:57098: write: broken pipe 519
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript