かばちんのエンジニアブログ

日々の経験の中で培った内容を備忘録も兼ねて記録していくブログです。少しでも誰かの役に立つために頑張って続けていけたらなと思います。

「ぬこしょうぎ」におけるリアルタイム通信

f:id:kabatin:20160907142256p:plain

リアルタイム将棋「ぬこしょうぎ」をリリース

先日こんなアプリをリリースさせて頂きました。
ぬこしょうぎ - ヤルキマントッキーズ株式会社


将棋をモチーフにコマの動きは将棋そのままで、将棋からターン制をバッサリと取り除いたゲームです。
ルールはシンプルなので将棋を知らない方でも楽しめる仕様になっています。

(不思議なことにターン制を取り除いてもやっぱり将棋を知っている人が若干有利になるようです!)


通信をどのような構成で、何を使ってやっているか

◆サーバサイド(コネクションサーバ)

クライアントからの WebSocket 接続を受け付けるサーバ。
知人が作成した nginx-luajit-websocket-pubsuber を利用して WebSocket 接続を受け付けている。
github.com


簡単に説明すると、nginx で接続を受け付けて WebSocket コネクションを維持し、
送られてきたデータを Disque に格納する仕組みです。(←この部分を lua が担っている)

※Disqueとは
Redis の開発者が作成した、オンメモリで動く Queue システムです。
github.com


◆サーバサイド(ゲームコンテキスト)

ゲームコンテキスト側ではとにかく Disque からデータが取得さえ出来ればあとは自由に処理ができます。
そこで利用したライブラリが、同じく知人が作成した Disquuun という C# で作成された Disque ライブラリです。
これにより、コネクションごとのデータを自由に出し入れできるようになります。
github.com


◆クライアントサイド(Unity 5.3.5p8)

クライアントからコネクションサーバに対して WebSocket 接続を行う必要があります。
利用したライブラリは、これまた同じく知人が作成した WebuSocket という C# で作成されたライブラリです。
github.com


全体の構成図

f:id:kabatin:20160907144618p:plain


この構成の最大の特徴1

何と言ってもこの構造で素晴らしい点、それは全てが非同期で行われているということです。
基本的に WebSocket 接続だと、何か送ったらそれをトリガーにしてサーバが処理を行い結果を返すと思います。
そうなってしまうと、サーバ側の処理が遅延した場合に後続の処理がすべて引きずられてしまいます。


この仕組みでは、クライアントから来た通信を元にまず nginx-lua が Disque にデータを格納します。
この時点でクライアントが送ったデータの処理は完了します。


その後、ゲームコンテキストがゲームループ周期のタイミングで Disque からデータを吸い上げて
結果を返すために必要な処理を行い、クライアントへ送るデータを Disque にまた書き出します。


そのデータを nginx-lua が Disque から吸い上げ、クライアントへデータを Push します。


この構成の最大の特徴2

サーバサイドの負荷の低さ、サーバコストの安さです。
IDCF の最も安価なサーバである S1 サーバ(月額200円+ディスク代300円=500円/月)で同時接続500人に耐えられます。


ぬこしょうぎでは、プレイタイムがだいたい1分〜2分前後であるのにも関わらず、
リリースして間もない時期に同時接続が70人を上回る時がありましたが、全く問題なく S1 サーバ1台で処理しています。


サーバのスペックをそれなりのものに変更すると、なんと20,000接続以上も耐えることができます。
もちろん1台でとにかく多くさばけばいいというものでもないので、リスクとのトレードオフがありますが
負荷の軽さについてはだいたい想像がついたのではないでしょうか。


UnityEditorとの相性の良さ

サーバサイド(ゲームコンテキスト)が C# で書かれているため、なんとUnity上でも動きます。
サーバサイドであるゲームコンテキストが Unity 上で動くので、個人端末でクライアントとサーバサイドの
両方を同時に開発することが可能になります。


世界初の DotNetCore 実用サービス

あくまで現時点での想定ではありますが、DotNetCore を実際に使用してリリースされた世界初のサービスです。
すでにお気付きの方もいらっしゃったかもしれませんが、サーバサイドを C# で書いているので Windows サーバだと
思った方も多いかもしれません。


が、しかし。
ぬこしょうぎは Ubuntu 14.04 LTS を利用してリアルタイム通信を実現しています。


そうです。
CoreCLR を利用して Linux上で C# のコードを動かしています。
Download .NET (Linux, macOS, and Windows)


まとめ

知人すごい。これに尽きる。

まだ大規模な実用で使われたことはない構成ではあるが、個人的にはものすごく理にかなった仕組みだと思っている。
開発のしやすさ、スケールのしやすさ、運用コストの低さ、負荷の低さ、どれを見ても群を抜いている気がする。

また UnityEditor 上でも動作する仕様上、開発のしやすさも兼ねておりいずれ標準的なモノになるのではないだろうか。
今後もこの仕組みを利用したアプリをたくさん出していきたい。