go言語の学習:websocketで画像を送信し、webで表示
できたの
なにこれ?
websocketサーバより1秒単位で画像をバイナリ形式で送信したもの
ソース(サーバ側)
package main import ( "log" "net/http" "golang.org/x/net/websocket" "time" "io/ioutil" "image" "gocv.io/x/gocv" "image/color" "bytes" "image/jpeg" "os/user" ) var ( black = color.RGBA{0, 0, 0, 0} ) func main() { name := "server" log.Println(name + " start") http.Handle("/ws", websocket.Handler(WsHandler)) err := http.ListenAndServe(":8001", nil) if err != nil { panic("ListenAndServe: " + err.Error()) } log.Println(name + " end") } func WsHandler(ws *websocket.Conn) { log.Println("connect") // 自動送信 go autoSend(ws) // 受信処理監視 for { var b []byte err := websocket.Message.Receive(ws, &b) if err != nil { log.Println(err) break } } } // 任意の画像を送信する func autoSend(ws *websocket.Conn) { t := time.NewTicker(1 * time.Second) for { select { case <-t.C: // ユーザディレクトリ取得 user, err := user.Current() if err != nil { log.Println(err) return } // 画像ファイル読み込み b, err := ioutil.ReadFile(user.HomeDir + "/Desktop/" + "pug3_pic1.jpg") if err != nil { break } // 画像変換 atom, err := gocv.IMDecode(b, gocv.IMReadUnchanged) if err != nil { log.Println(err) return } defer atom.Close() // 日時取得 now := time.Now() // 偶数 if int(now.Second()) % 2 == 0 { gocv.Rectangle(&atom, image.Rect(400, 400, 900, 700), black, 2) } else { gocv.Rectangle(&atom, image.Rect(400, 400, 900, 700), black, -1) } // 文字列を出力 timeStr := now.Format("2006/01/02 15:04:05") gocv.PutText(&atom, timeStr, image.Pt(20, atom.Rows() - 40), gocv.FontHersheyComplex, 1, black, 1) // 画像に変換 image, err := atom.ToImage() if err != nil { log.Println(err) return } var jpegBytes []byte buf := bytes.NewBuffer(jpegBytes) if err := jpeg.Encode(buf, image, nil); err != nil { log.Println(err) } b = buf.Bytes() websocket.Message.Send(ws, b) log.Println("send") } } }
ソース(クライアント側)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <img id="img1" src=""> <script> var uri = "ws://localhost:8001" + "/ws"; webSocket = new WebSocket(uri); webSocket.binaryType = 'blob'; webSocket.onopen = function(e) { console.log("open"); }; webSocket.onmessage = function(e) { console.log("message"); var data = e.data; if (data.constructor === Blob) { document.getElementById('img1').src = URL.createObjectURL(data); } }; webSocket.onclose = function(e) { console.log("close"); }; </script> </body> </html>
ソース(クライアント版2)
package main import ( "log" "golang.org/x/net/websocket" "strconv" ) var ( doneCh chan bool origin = "http://localhost:8001/" url = "ws://localhost:8001/ws" ) func main() { name := "client" log.Println(name + " start") doneCh = make(chan bool) ws, err := websocket.Dial(url, "", origin) if err != nil { log.Fatal(err) return } go receiveMsg(ws) <-doneCh log.Println(name + " end") } // 受信 func receiveMsg(ws *websocket.Conn) { var b []byte for { err := websocket.Message.Receive(ws, &b) if err != nil { log.Println(err) doneCh <- true break } log.Printf("Receive datasize=" + strconv.Itoa(len(b))) } }
所感
いろいろ悩んだけど基本は画像をバイナリで送信するだけだった感じ
動画のストリーミングという感じではないのでそこまで難しくないかも…
最初はwebsocketの送受信がうまく行かなかったけどw