[Go] http、chunked、切断検知、TimeOut、channelのclose

Push配信するhttpサーバーを目指すサンプル。

盛り込んだ要素は下記の通り。

  1. httpサーバー
    →普通です。すみません。
  2. Transfer-Encoding: chunked
    →しょっぱなにw.WriteHeader(http.StatusOK)、
     そして、w.(http.Flusher).Flush()
  3. goroutine&channel
  4. time.Sleep
    →渡す値は、単位を掛ける。
  5. channelのcloseとその検知方法
    →close()は組み込み関数。
     そしてchannel受信には2番目の戻り値があることを知れ
  6. timeoutを仕掛ける方法
    time.Afterでchannelゲットだぜ
  7. 通信切断の検知方法
    →w.(http.CloseNotifier).CloseNotify()でchannelゲットだぜ
  8. 複数channelの同時受信
    →selectをforで無限ループだぜ。あとラベル付きbreak。
  9. ロギング
    →log.Println()だぜ。


盛りだくさんだぜ~

package main
import (
"fmt"
"log"
"net/http"
"time"
)
func outln(w http.ResponseWriter, mes string) {
w.Write([]byte(mes))
w.Write([]byte("\n"))
w.(http.Flusher).Flush()
log.Println(mes)
}
func handler(w http.ResponseWriter, r *http.Request) {
// Transfer-Encoding: chunked
w.WriteHeader(http.StatusOK)
outln(w, "start")
// for over
times := 5
// for TimeOut
//times := 10
// メッセージを送る人
ch := make(chan string)
go func() {
for i := 0; i < times; i++ {
time.Sleep(time.Second * 1)
ch <- fmt.Sprintf("hoge:%d", i)
}
close(ch)
}()
// 時間制限は10秒
timeout := time.After(time.Second * 10)
// 通信切断されたら抜ける
closeNotify := w.(http.CloseNotifier).CloseNotify()
// 何かしら結果が出るまでループする
Loop:
for {
select {
case mes, ok := <-ch:
if ok {
outln(w, mes)
} else {
outln(w, "message is over")
break Loop
}
case <-closeNotify:
log.Println("session closed")
break Loop
case <-timeout:
outln(w, "process timeout")
break Loop
}
}
outln(w, "bye")
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8085", nil)
}
view raw main.go hosted with ❤ by GitHub

コメント

このブログの人気の投稿

Android・・・テキスト描画あれこれ, ascent(), descent()等

nginxでlocalhostとしてアクセスをサーバーに転送する方法

Android:stateに応じてTextの色を変更する・・・ColorStateList