要在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.Printf("Server started at port %v", port)
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
}