【GO】Websocketによる通信


websocketを使ってサーバーとの相互通信をしたい。

gin-gonic/gingorilla/websocket を使って動作確認してみます。

WebSocketの基本

従来のクライアント起点の通信から、サーバ・クライアント間の双方向通信のために作られた仕組み。

http:https:のかわりにws:wss:というURIスキームを用いる。

GOパッケージ / WebSocket

公式の拡張パッケージがありますが、他のパッケージにある機能が欠けてるとのことなのでgorilla/websocketを使用します。

githubを眺めるとgobwas/wsolahol/melodyなんかも気になるところ。

特にmelodyはjavascriptっぽいイベントハンドリングが出来そうに見える。

サンプル

基本的なクライアント・サーバー処理は examples/echo がわかりやすいです。

外部だとBitFlyerの仮想通貨APIがgorillaでjson-rpc使用のサンプルがありました。

BitFlyerのサンプルはそのままだと -32600 Invalid Request となるので送受信JSONを分けて使うように変更が必要です。

クライアント処理

コードはexamples/echoを見るとして基本的に3ステップです。

  • コネクションを張る
  • 受信用のルーチンを作る
  • (定期的に何か送ったりしつつ)待機する

ReadMessage/ReadJSONで受信処理し、WriteMessage/WriteJSONで送信処理します。

サーバ処理

こっちはもっとシンプルに2ステップ。

  • Upgraderをセットアップ
  • 受信を待ったり(クライアント主動)、タイマーなんかのイベント(サーバ主動)を待って送信する

サンプルコード

1ファイルでサーバーとクライアントを同時に立ち上げるサンプルです。

サンプルつぎはぎですがクライアント側はOSシグナル処理をすると終了時にサーバのみ生き残ってしまうのでコメントアウトしています。

クライアント側処理で時間をrecv:していれば成功です。

 

このコードだとgo clientStart()を増やすとそれぞれにタイマーが動きます。

ちゃんとブロードキャスト(一斉送信)したい場合にはコネクションを保存しておく必要があります。ちょうどその管理をしているのがexamples/chatのHubです。

今回のサンプルで簡潔に書くとこんな感じ。

これでサーバーイベントに沿ってクライアントに一斉送信します。

メモリ管理

サーバのUpgraderでバッファの管理をしています。試しにこんな感じで実行。

タスクマネージャでメモリを見たところサンプル通りの1クライアント接続で70MB、3クライアントのルーチンにしてみたら200MBになった。

ReadBufferSize and WriteBufferSize specify I/O buffer sizes in bytes

らしいので(1GB+1GB) * クライアント数で6Gかと思ったけどそうでもない。

ただバッファサイズとクライアント数に比例して必要メモリ量が増えます。

なのでクローズ管理はちゃんとやらないといけない。


コメントを残す

メールアドレスが公開されることはありません。