golang web server如何知道client是否已经断开

golang web server如何知道client是否已经断开

背景

在web http服务中有些时候如果请求的服务端运行时间比较长,而在其中客户端放弃了请求,那么此时服务端可以迅速放弃正在进行的操作,因为也不能把结果返回给客户端了,否则也是浪费资源,甚至产生副作用。

如何解决这个问题

golang的Context可以用来处理这种场景。

详细请参考Context的文档:https://blog.golang.org/context

举例

服务端代码:

package main

import (
    "fmt"
    "log"
    "time"
    "net/http"

    "github.com/gorilla/mux"
)

func main() {
    address := fmt.Sprintf("%s:%d", "0.0.0.0", 8080)
    router  := mux.NewRouter().StrictSlash(true)

    router.HandleFunc("/test", testHandle)
    err := http.ListenAndServe(address, router)
    if err != nil {
        log.Panic("ListenAndServe err:", err)
    }
}

func testHandle(w http.ResponseWriter, r *http.Request) {
    log.Printf("Client request is coming\n");
    ctx := r.Context()

    time.Sleep(10 * time.Second)

    select {
    case <-ctx.Done():
        log.Printf("\tClient has broken\n");
        break
    default:
        log.Printf("\tSend client response\n");
        w.Write([]byte("I am OK"))
    }
}

这个服务器提供一个localhost:8080/test的URL请求服务,这个服务需要10秒,然后返回"I am OK"给client端,因为在10秒时间间隔内,客户端可能放弃请求,那么server能感应到客户端是否已经放弃了请求。

客户端调用:

  • case 1: 正常未放弃
    客户端输出:
$ time curl localhost:8080/test             
I am OK
real    0m10.012s
user    0m0.003s
sys     0m0.004s

server段输出:

$ go build && ./test 
2019/05/20 03:22:51 Client request is coming
2019/05/20 03:23:01     Send client response
  • case 2: client端中途放弃
    client端输出:
$ time curl --max-time 5 localhost:8080/test
curl: (28) Operation timed out after 5000 milliseconds with 0 out of -1 bytes received

real    0m5.006s
user    0m0.001s
sys     0m0.005s

server端输出:

$ go build && ./test 
2019/05/20 03:24:45 Client request is coming
2019/05/20 03:24:55     Client has broken
  • case 3:通过浏览器测试
    可以通过关闭浏览器页面的方式来模拟client放弃操作。可以达到同样的server端效果。
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容