如何在 *tls.Conn 上设置 SetKeepAlivePeriod

我想增加 HTTP 和 HTTPS 请求的 TCP 连接的保持活动时间。


对于 HTTP 请求,可以这样完成:


package main


import (

    "fmt"

    "io"

    "log"

    "net"

    "net/http"

    "time"

)


func main() {

    server := &http.Server{Addr: ":8080", Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

        io.WriteString(w, "Hello, World!")

    })}


    server.ConnState = func(conn net.Conn, state http.ConnState) {

        if state == http.StateNew {

            if err := conn.(*net.TCPConn).SetKeepAlivePeriod(1000 * time.Second); err != nil {

                fmt.Println("Could not set keep alive period", err)

            } else {

                fmt.Println("update keep alive period")

            }

        }

    }


    log.Fatal(server.ListenAndServe())

}

对于 HTTPS 请求,这不能通过,server.ConnState因为net.Conn将在函数内部传递的是*tls.Conn. 此连接不会公开类似的功能SetKeepAlivePeriod或提供对底层*net.TCPConn.


func main() {

    server := &http.Server{Addr: ":8080", Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

        io.WriteString(w, "Hello, World!")

    })}


    server.ConnState = func(conn net.Conn, state http.ConnState) {

        if state == http.StateNew {

            tlsConn := conn.(*tls.Conn)

            // how to set SetKeepAlivePeriod

        }

    }


    log.Fatal(server.ListenAndServeTLS("../example.crt", "../example.key"))

}

如何设置 tls 连接的保活期?


手掌心
浏览 143回答 1
1回答

qq_笑_17

有(至少)两种方法可以做到:使用net.ListenConfig:该net.ListenConfig对象有一个KeepAlive time.Duration字段。当非零时,这将用于在接受的连接上设置保持活动状态(例如:对于 posix 上的 TCP)。您可以将侦听器传递给ServeTLS:server := &http.Server{...}lc := net.ListenConfig{KeepAlive: 1000 * time.Second}ln, err := lc.Listen(context.Background(), "tcp", ":8080")if err != nil {  panic(err)}defer ln.Close()log.Fatal(server.ServeTLS(ln, "../example.crt", "../example.key"))如前所述,接受的 TCP 连接将自动启用 keep-alive 并将周期设置为指定值。使用tls.Config回调:您可以通过设置tls.Config或回调来访问net.Conn底层。tls.Conn GetConfigForClientGetCertificate只要您返回nil以使 TLS 代码回退到默认行为,您使用哪一个都没有关系。重要的部分是访问tls.ClientHelloInfo,它有一个.Conn指向底层连接的字段。这将net.TCPConn.setTCPKeepAlive := func(clientHello *tls.ClientHelloInfo) (*tls.Config, error) {  // Check that the underlying connection really is TCP.  if tcpConn, ok := clientHello.Conn.(*net.TCPConn); ok {    if err := tcpConn.SetKeepAlivePeriod(1000 * time.Second); err != nil {      fmt.Println("Could not set keep alive period", err)    } else {      fmt.Println("update keep alive period")    }  } else {    fmt.Println("TLS over non-TCP connection")  }  // Make sure to return nil, nil to let the caller fall back on the default behavior.  return nil, nil}tlsConfig := &tls.Config{    ...    GetConfigForClient: setTCPKeepAlive,    ...}server := &http.Server{    Addr:      ":8080",    TLSConfig: tlsConfig,}server.ListenAndServeTLS("../example.crt", "../example.key")
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go