要在 Not_a_Golfer 提到的 goroutine 中运行 ListenAndServe,您可以使用无缓冲的阻塞通道在 goroutine 中运行它并保持服务器处于活动状态。
以下示例创建了一个名为done 的通道,其中<-done 将在等待goroutine 完成时使服务器保持活动状态,在这种情况下不会。通常,goroutine 会通过执行done <- true 来告诉主函数它已完成。
package main
import (
"log"
"net/http"
)
func MyHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello World"))
}
func main() {
port := "8080"
http.HandleFunc("/", MyHandler)
done := make(chan bool)
go http.ListenAndServe(":"+port, nil)
log.Printf("Server started at port %v", port)
<-done
}
这是一个更大的示例,让服务器验证它是否可以运行,分别使用Listen 和Serve。这样做的好处是您可以轻松捕获错误的端口。
package main
import (
"log"
"net"
"net/http"
"os"
)
func MyHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello World"))
}
func main() {
port := "8080"
http.HandleFunc("/", MyHandler)
listener, err := net.Listen("tcp", ":"+port)
if err != nil {
log.Fatal(err)
}
done := make(chan bool)
go http.Serve(listener, nil)
// Log server started
log.Printf("Server started at port %v", port)
// Attempt to connect
log.Printf("Fetching...")
res, err := http.Get("http://" + listener.Addr().String())
log.Printf("Received: %v, %v", res, err)
if err != nil {
log.Fatal(err)
}
res.Write(os.Stdout)
<-done
}