Golang 如何在 HTTP Sever 端口监听成功后执行一些操作
大约 2 分钟...
在 Golang
中直接使用 ListenAndServe()
如果监听成功则会阻塞后续代码, 导致无法知道端口监听是何时建立成功的。ListenAndServe
包含两步操作:
- 1)监听端口
- 2)accept 以阻塞方式等待接受请求; 如果 1)执行成功,会立即进入阻塞状态,后面的代码在 shutdown 之前都无法执行
所以如果想在端口监听成功时输出一条日志,则需要单独建立 net.Listener 再传给 Serve 函数,具体代码如下:
改造后 Serve
// 可以在监听成功后继续执行其他代码
func httpServe() {
httpHandler := http.DefaultServeMux
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "hello")
})
addr := ":8080"
srv := http.Server{
Addr: addr,
Handler: httpHandler,
}
// 监听端口
ln, err := net.Listen("tcp", srv.Addr)
if err != nil {
log.Fatalf(err.Error())
return
}
log.Printf("listen on %s", addr) // 这里可以执行自定义的逻辑
// 这里成功后会阻塞
if err := srv.Serve(ln); err != nil && err != http.ErrServerClosed {
log.Fatalf("server error: %v", err)
}
// 下面的代码无法执行
// ...
}
改造前 ListenAndServe
// 阻塞后无法执行后续代码
func httpListenAndServe() {
httpHandler := http.DefaultServeMux
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "hello")
})
addr := ":8080"
srv := http.Server{
Addr: addr,
Handler: httpHandler,
}
// 这里成功后会阻塞
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("server error: %v", err)
}
// 下面的代码无法执行
// ...
}
gin
版实现:
Serve
// 可以在监听成功后继续执行其他代码
func httpServe() {
ginSrv := gin.New()
addr := ":8080"
srv := http.Server{
Addr: addr,
Handler: ginSrv,
}
// 监听端口
ln, err := net.Listen("tcp", srv.Addr)
if err != nil {
log.Fatalf(err.Error())
return
}
log.Printf("listen on %s", addr) // 这里可以执行自定义的逻辑
// 这里成功后会阻塞
if err := srv.Serve(ln); err != nil && err != http.ErrServerClosed {
log.Fatalf("server error: %v", err)
}
// 下面的代码无法执行
// ...
}
ListenAndServe
// 阻塞后无法执行后续代码
func httpListenAndServe() {
ginSrv := gin.New()
addr := ":8080"
srv := http.Server{
Addr: addr,
Handler: ginSrv,
}
// 这里成功后会阻塞
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("server error: %v", err)
}
// 下面的代码无法执行
// ...
}
参考:https://blog.csdn.net/pengpengzhou/article/details/109811779 Go 语言:如何在 HTTP Sever 服务端端口监听成功时输出一条日志