AWS に GameLift というサービスがある。これを使うとゲームサーバ(*)を勝手にスケールしてくれるなどいい感じにマネージしてくれるらしい。
(*GameLift がいうところのゲームサーバは、いわゆる API サーバではなく、いわゆる Dedicated Game Server の方。Ark やマインクラフトなどマルチプレイ用サーバを自分で立てられるゲームで遊んだことがある人ならイメージしやすいと思う)
GameLift を使うには、GameLift Server SDK を組み込んだゲームサーバを作って、GameLift にアップロードする必要がある。GameLift Server SDK というのは、GameLift がゲームサーバを管理するための各種処理をやるやつで、公式には C++と C#の SDK が提供されている。あと非公式な port としてNode.js 版がある。前回の記事の通り Go でサーバもクライアントも書きたい気分なので、今回は Go 用の Server SDK を作ってみたい。
Server SDK の内容は、おおまかには以下の通り。
- ローカルホストに起動している GameLift 管理サーバに対して、Socket.IO の接続を 2 本確立する。1 本は受信用、もう 1 本は送信用として利用する()
- ゲームサーバの準備ができたタイミングで GameLift に通知すると、GameLift からセッション作成要求が来た際にコールバックが呼ばれる
- 接続を確立したあとは定期的に死活チェックを行う
- 通信されるメッセージは Protocol Buffers でシリアライズを行う
ということは、Socket.IO と Protocol Buffers がなんとかなればよさそう。
幸い Go には Socket.IO のクライアントを実装したgomasioというライブラリがあって、Protocol Buffers は Google がサポートしているライブラリがあり、Protocol の定義ファイルは前述の Node.js 版の著者が公開してるしで、割と簡単にいけそうな気がする。
https://gist.github.com/neguse/1881c8d291eebf15a2a3f8c36a8ee4bf
ということでやってみている途中のコードがこちらになります。
とりあえずテスト用のローカルで起動する GameLiftLocal というサーバに接続して、StartGameSession が呼ばれるところまでは確認できた。次に Ack を返さないといけないらしいのだけど、ちょっと方法が見つからなくて、どうすれバイインダーというところで今日は以上です。
- GameLift Server SDK は Process ID や SDK のバージョンを URL のクエリストリングで受け取るようになっているが、現状 gomasio にはクエリストリングを渡す方法が無いため、無理やり RawQuery を上書きしている。
- gomasio はイベント受信時のコールバックに渡される Context 引数経由でイベントを Emit できるようになっているが、ヘルスチェックやサーバの準備ができたことの通知などでコールバック外からイベントを Emit したい。socketio.NewContext()を呼ぶことで無理やり外部から Context を作っているが、これでいいのか感がある。packet 引数に nil 渡すと死ぬし…
- Socket.IO と、それのベースになっている Engine.IO はシンプルそうなので、自前で実装してもよいかもしれない。(だんだん本題からそれていきそう)