自分用めも

初心者ちっくなプログラムネタを中心に、自分用の覚え書きをメモっていくための場所です。

Nginxでecho(golang)でWebSocket 「github.com/gorilla/websocket」編

前回に続き、今度はgorillaのパッケージを使って実装してみます。

前回同様、「echoとnginxにおけるwebsocket設定」が趣旨であり、
メインロジックには以下のサンプルチャットを使っています。
github.com

Nginx側

前回とほぼ一緒ですが、モジュールをgorillaに変えた結果、一箇所追加対応が必要になりました。
これはgorillaが悪いということではなく、
むしろ公式のwebsocketモジュールに穴があったのかも?という感じです…。

vim /srv/www/nginx.conf
server {
	#~略~
	location /ws {
		proxy_pass http://goecho_socket_server;
		proxy_http_version 1.1;
		proxy_set_header Host $host;
		proxy_set_header Upgrade $http_upgrade;
		proxy_set_header Connection "upgrade";
		proxy_read_timeout 6h;
	}
	#~略~
}

今回追加したのは「proxy_set_header Host $host;」の部分です。

これは何かといいますと、websocketではhttpのヘッダ情報を書き換えることで通常の接続の様に見せかけながらwebsocket接続を行うのですが、書き換える際にヘッダ情報が無くなってしまっていた?ようで、それをアクセス時のヘッダ情報で書き戻してやるという設定になります。

gorillaではwebsocket時のセキュリティを担保するためにドメインの同一性チェック(クロスドメインを認めない)を行っており、上記設定がない場合、下記エラーで異常終了してしまいます。

websocket: request origin not allowed by Upgrader.CheckOrigin

今回はその対応のためにヘッダ情報を正しく設定し直したわけですが、「golang.org/x/net/websocket」ではそれをしなくても普通に通っていたわけです。

go-echo側

前回と同じで、サンプルのうちmain.go以外を使います。
mein.goについては自前で前回構築した物に取り入れます。

package main

func main() {
	//~略~

	// WebSocket ------
	hub := newHub()
	go hub.run()
	e.GET("/ws", func (c echo.Context) error {
		serveWs(hub, c.Response(), c.Request())
		return nil
	})

	//~略~
}

これだけです。
Hubというのがサーバインスタンスにあたり、main関数内で一度だけ生成してイベントハンドラに渡してやります。
機能的には前回のサンプルよりもシンプルなようです。

以上簡単ですが、疎通まで。