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関数内で一度だけ生成してイベントハンドラに渡してやります。
機能的には前回のサンプルよりもシンプルなようです。
以上簡単ですが、疎通まで。