バックグラウンドでHTTPサーバを起動する
サーバをインスタンス化する
HTTPサーバを起動する場合、
http.ListenAndServe()
を利用しますが、HTTPサーバをバックグラウンドで実行したい場合、これではHTTPサーバをシャットダウンすることができません。
http.Serverインスタンスを利用する
http.ListenAndServe() は中身を見ればわかると思いますが、http.Serverインスタンスを作成しているだけなのでAddrとHandlerを設定して上げるだけで動作します。
var srv http.Server srv.Addr = "localhost:8080" srv.Handler = http.FileServer(http.FS(fs)) go func() { srv.ListenAndServe() } () ... srv.Shutdown() //終了したい場合Shutdown()を呼ぶ
ポート番号を固定しない
ポート番号を0に設定すると空いているポートを発行してくれます。 ただ、上記のようにListenAndServe() ではその発行したポートを知ることができない為、どこにアクセスしていいかわからなくなります。 そういう場合はListen and Serve ではなく個別にListen とServeを行います。
net.Listen() を利用して一旦net.Listenerを生成しておいて、Addr() で知ることができます。
ln, err := net.Listen("tcp", "127.0.0.1:0") fmt.Println(ln.Addr().String()) err = server.Serve(ln)
http.Server.Serve()の戻り値
忘れがちですがListenAndServe() もそうですが、起動できなかった場合などにerrorを返してくれてます。 Server.Shutdown() を利用するとServe()はerrorを返して終了する為、 起動した時にしっかりエラー処理を行っていると注意が必要です。
cs.opensource.google/go/go/+/refs/tags/go1.21.6:src/net/http/server.go;l=3059
自分でShutdown() を行ったらフラグなどを利用して、http.ErrServerClosedを判定する必要があります。
err := srv.Serve(ln) if err != nil { if isShutdown() && errors.Is(err,http.ErrServerClosed) { //無視 } }
アドレスとポートを連結する
よくアドレスを作成する時に
addr := fmt.Sprintf("%s:%d",host,port)
※IPv6時にHostを”[]"でくくってくれます。
を行いますが、IPv6時に動作しません。 net.JoinHostPort() を利用しておくと安全です。
net.JoinHostPort(host, strconv.Itoa(port))
The Go gopher was designed by Renee French.
The design is licensed under the Creative Commons 3.0 Attributions license. Read this article for more details: