🌀
GoでHTTP Streaming
概要
WebSocketやHTTP/2を使わず、レスポンスをストリームで受け取ることができる
実装
server
server.go
package main
import (
"log"
"net/http"
"net/http/httputil"
"time"
)
func stream(w http.ResponseWriter, r *http.Request) {
flusher, _ := w.(http.Flusher)
cw := httputil.NewChunkedWriter(w)
for i := 0; i < 3; i++ {
cw.Write([]byte("hello"))
flusher.Flush()
time.Sleep(time.Second)
}
}
func main() {
http.HandleFunc("/", stream)
log.Fatal(http.ListenAndServe(":8080", nil))
}
$ go run server.go
$ curl localhost:8080 -i
HTTP/1.1 200 OK
Date: Wed, 27 Jul 2022 02:00:48 GMT
Content-Type: text/plain; charset=utf-8
Transfer-Encoding: chunked
5
hello
5
hello
5
hello
client
client.go
package main
import (
"io"
"log"
"net/http"
"net/http/httputil"
)
func main() {
resp, err := http.Get("http://localhost:8080")
if err != nil {
log.Fatal(err)
}
if resp.StatusCode != http.StatusOK {
log.Fatal(resp.Status)
}
cr := httputil.NewChunkedReader(resp.Body)
for {
buf := make([]byte, 5)
n, err := cr.Read(buf)
if err == io.EOF || err == io.ErrUnexpectedEOF {
break
}
if err != nil {
log.Fatal(err)
}
log.Println(string(buf[:n]))
}
}
$ go run client.go
2022/07/27 11:04:50 hello
2022/07/27 11:04:51 hello
2022/07/27 11:04:52 hello
参考
Discussion