如何在 *tls.Conn 上设置 SetKeepAlivePeriod
How to set SetKeepAlivePeriod on a *tls.Conn
我想增加 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连接的存活时间?
有(至少)两种方法:
使用 net.ListenConfig:
net.ListenConfig
对象有一个 KeepAlive time.Duration
字段。当 non-zero 时,这将用于在接受的连接上设置 keep-alive(例如:for TCP on posix)。
您可以将侦听器传递给 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 GetConfigForClient
或 GetCertificate
回调来访问 tls.Conn
底层的 net.Conn
。
只要您 return 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")
我想增加 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连接的存活时间?
有(至少)两种方法:
使用 net.ListenConfig:
net.ListenConfig
对象有一个 KeepAlive time.Duration
字段。当 non-zero 时,这将用于在接受的连接上设置 keep-alive(例如:for TCP on posix)。
您可以将侦听器传递给 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 GetConfigForClient
或 GetCertificate
回调来访问 tls.Conn
底层的 net.Conn
。
只要您 return 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")