※注意: この記事ははあくまで個人学習用に整理しただけの記事で、内容としては不完全なものになります。読んでも参考にならない可能性が高いです。
go を学習していて、Web サーバーの作成方法がいくつもあったので、自分の整理用にまとめる。
パターンその1
handler というハンドラ関数を定義
- http.HandleFunc を使用
- index という handler 関数を別で定義し、http.HandleFunc の第二引数に関数を渡す
- 最後に http.ListenAndServe 実行
package main
import (
"fmt"
"net/http"
)
func index(writer http.ResponseWriter, request *http.Request) {
// 省略
}
func main() {
http.HandleFunc("/", index)
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatal("ListenAndServe:", err)
}
}
パターンその2
templateHandler、独自のハンドラを作成
- http.Handle を使用
- 最後に http.ListenAndServe 実行
package main
import (
"html/template"
"net/http"
)
type templateHandler struct {
once synce.Once
filename string
templ *template.Template
}
func (t *templateHander) ServeHTTP(w http.ResponseWriter, r *http.Request) {
t.once.Do(func() {
t.templ = template.Must(template.ParseFiles(filepath.Join("templates", t.filename)))
})
t.templ.Execute(w, nil)
}
func main() {
http.Handle("/", &templateHandler{filename: "index.html"})
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatal("ListenAndServe:", err)
}
}
templates/index.html
<html>
<head>
<title>index</title>
</head>
<body>
<div>index</div>
</body>
</html>
パターンその3
templateHandler、独自のハンドラを作成
- http.NewServeMux() で mux(マルチプレクサ)を作成
- mux.HandleFunc に URL パターンと index handler 関数を渡す
- http.Server 構造体のポインタで初期化。その際に Handler field に mux を渡す
- 初期化したものを server 変数へ代入
- 最後に server の ListenAndServe メソッドを実行
package main
import (
"net/http"
"time"
)
func index(writer http.ResponseWriter, request *http.Request) {
// 省略
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", index)
server := &http.Server{
Addr: config.Address,
Handler: mux,
ReadTimeout: time.Duration(config.ReadTimeout * int64(time.Second)),
WriteTimeout: time.Duration(config.WriteTimeout * int64(time.Second)),
MaxHeaderBytes: 1 << 20,
}
server.ListenAndServe()
}
http.Server という構造体は以下のようになっている
https://golang.org/src/net/http/server.go?h=ListenAndServe#L2520
type Server struct {
Addr string
Handler Handler // handler to invoke, http.DefaultServeMux if nil
TLSConfig *tls.Config
ReadTimeout time.Duration
ReadHeaderTimeout time.Duration
WriteTimeout time.Duration
IdleTimeout time.Duration
MaxHeaderBytes int
TLSNextProto map[string]func(*Server, *tls.Conn, Handler)
ConnState func(net.Conn, ConnState)
ErrorLog *log.Logger
BaseContext func(net.Listener) context.Context
ConnContext func(ctx context.Context, c net.Conn) context.Context
inShutdown atomicBool
disableKeepAlives int32
nextProtoOnce sync.Once
nextProtoErr error
mu sync.Mutex
listeners map[*net.Listener]struct{}
activeConn map[*conn]struct{}
doneChan chan struct{}
onShutdown []func()
}
Server struct の Handler field に http.NewServeMux() で作成したマルチプレクサを登録しているようだ。
他にもパターンを発見したら随時更新していく。