はじめに
今回はwebsocket-sharpを用いてリアルタイムな通信をしてみる記事になります!
このwebsocket-sharp
というライブラリを使うことで、手軽にオンラインゲームといったリアルタイムに通信が必要なものを実装できます。
またサーバーとクライアントの両方をこのライブラリで対応しているので、Unityとこのライブラリだけでどちらも実装できるのも魅力の一つですね。
では早速みていきましょう。
websocketとは?
このライブラリの名前にもあるwebsocket
ですが、以下のような意味があるようです。
Webにおいて双方向通信を低コストで行うための仕組み。プロトコルの一種。
今さら聞けないWebSocket~WebSocketとは~ - Qiita
オンラインゲームのような複数によるリアルタイムなやり取りに向いているというわけですね。
下準備
websocket-sharp
は残念ながらAssetStoreにはないみたいなので、GitHubからダウンロードして自分でビルドする必要があります。
cloneをしてもいいですが、Download Zip
の方に今回はします。すると.zip
のファイルがダウンロードできるので、解凍しましょう。
サンプルは必要ないのでExample
を削除し、websocket-sharp.sln
をVisual Studioで開きます。
ここでビルドしようとしたところエラーが出てしまったので、少しだけコードを追加します。
CookieException.cs
修正前
[Serializable] public class CookieException : FormatException
↓
修正後
[Serializable] public class CookieException : FormatException, ISerializable
修正ができたらビルドし、出力のところに.dll
のパスが表示されているので確認してみましょう。
websocket-sharp.dll
をUnityのPlugins
フォルダに入れれば下準備は終了です。
サーバー側の実装をする
using UnityEngine; using WebSocketSharp; using WebSocketSharp.Server; public class WSServer : MonoBehaviour { private WebSocketServer _server; private void Start() { _server = new WebSocketServer(3000); _server.AddWebSocketService<Echo>("/"); _server.Start(); } private void OnDestroy() { _server.Stop(); _server = null; } public class Echo : WebSocketBehavior { protected override void OnMessage(MessageEventArgs e) { Sessions.Broadcast(e.Data); Debug.Log(e.Data); } } }
これがサーバー側のスクリプトになります。
WebSocketServer
のコンストラクタによりポート番号を設定できます。
WebSocketBehavior
を継承したクラスには、メッセージをサーバーが受信したときの処理をOnMessage
に書きました。
今回はこれだけですが、コネクションを確立したときのOnOpen
,エラーが発生したときのOnError
,接続を切断したときのOnClose
は必要に応じて書き加えても良いでしょう。
そしてWebSocketBehavior.Sessions.Broadcast
メソッドによってクライアントから受け取ったメッセージをそのまますべてのクライアントに送信しています。
試してみる
サーバー側のスクリプトがちゃんと動くのか見てみます。
動作を確認するためにwscat
を用いることで簡単にできます。
WebSocket の動作確認に wscat が便利すぎる件 - tricknotesのぼうけんのしょ
ただこれはNode.jsが必要なので、まだインストールしていない方は以下の記事を参考に設定してみてください。
Node.jsをWindows10にインストールする方法 - Qiita
インストールができら以下のコマンドをコマンドプロンプト等で打ち込みます。
$ npm install -g wscat
準備が整ったら、以下のコマンドにてサーバー繋ぐことができます。
(ポート番号が3000の場合)
$ wscat -c ws://localhost:3000
実際にUnityで上のサーバー側のコードを書いたものをゲームオブジェクトにアタッチした後再生ボタンを押し、wscat
でサーバーにつないでみてください。
クライアント側の実装する
using UnityEngine; using WebSocketSharp; public class WSClient : MonoBehaviour { private WebSocket _webSocket; private const string WEBSOCKET_URL = "ws://localhost3000/"; private void Start() { _webSocket = new WebSocket(WEBSOCKET_URL); _webSocket.OnMessage += (sender, e) => Debug.Log(e.Data); _webSocket.OnClose += (sender, e) => Debug.Log("Close"); _webSocket.Connect(); } private void Update() { if (Input.GetKeyDown("s")) _webSocket.Send("Send a message"); } private void OnDestroy() { _webSocket.Close(); _webSocket = null; } }
WebSocket
のコンストラクタでWebSocket
のURLを設定します。
そしてメッセージを受け取ったときのOnMessage
,通信を終了したときのOnClose
のイベントを。
さきほどと同様にOnOpen
,OnError
もつけても良いと思います。
またWebSocket.Open
・Send
・Close
はともにOpenAsync
のように書くことで非同期にできるようです。
さいごに
このサーバーのスクリプトを含むシーンをLinux向け等にビルドして、自前のサーバーやレンタルサーバー(VPSとかEC2とか?)で動作させるとまさにオンラインゲームの完成です。
色々なことに応用できると思うので、かなり夢が広がりますね!