http服务器启动时是否有任何方法可以打印?例如"Server is started at port 8080"
在Node(使用Express)中,它就像:
app.listen(8080, function() { console.log('Server started at port 8080') });
这是我的代码:
func main() {
http.HandleFunc("/", MyHandler)
http.ListenAndServe(":8080", nil)
}
感谢。
答案 0 :(得分:8)
您无法在ListenAndServe
之后打印日志消息,因为它会阻止并且永不返回,因此基本上您有两个主要选项:
打印“在端口上启动服务器......”就是这样 - 但是如果ListenAndServe
无法启动它会返回错误,所以除非因为这个而打印出一些错误或恐慌,否则你可以假设服务器已启动。
在单独的goroutine中调用ListenAndServe
,并确保没有返回错误并打印“服务器已启动...”等。
我个人更喜欢第一种方法。
答案 1 :(得分:8)
使用Go的log包:
package main
import (
"net/http"
"log"
)
func main() {
addr := ":8080"
http.HandleFunc("/", MyHandler)
log.Println("listen on", addr)
log.Fatal( http.ListenAndServe(addr, nil) )
}
http.ListenAndServe
打开服务器端口,并永久阻止等待客户端。如果无法打开端口,log.Fatal
呼叫将报告问题并退出程序。
答案 2 :(得分:3)
要在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
}