Contenu connexe
Similaire à Unity WebSocket
Similaire à Unity WebSocket (20)
Unity WebSocket
- 2. Contents
WebSocketの紹介
WebSocketを使ったデモ(ブラウザ・Unity)
WebSocketのメリット・デメリット
まとめ
12年10月4日木曜日 2
- 3. 自己紹介
2006年にシステム屋からアプリ開発者に
2008年頃から、携帯電話向けオンラインゲー
ムの主にサーバを担当(iアプリ)
2012年2月にセガへ転職し、現在はUnityを
使ったスマートフォン向けオンラインゲームを
開発中
12年10月4日木曜日 3
- 5. WebSocketとは
コンピュータ・ネットワーク用の通信規格の1
つ。W3CとIETFがウェブサーバーとウェブブ
ラウザとの間の通信のために規定を予定して
いる双方向通信用の技術規格であり、APIは
W3Cが、WebSocket プロトコルはIETFが策定
に関与している。プロトコルの仕様は RFC
6455。TCP上で動く。(Wikipediaより引用)
12年10月4日木曜日 5
- 10. リアルタイム通信が出来る
ゲームサーバ
WebSocketの
コネクション
ユーザA ユーザB
12年10月4日木曜日 10
- 11. リアルタイム通信が出来る
ゲームサーバ
① 移動先を
クリック
ユーザA ユーザB
12年10月4日木曜日 11
- 12. リアルタイム通信が出来る
② 移動先座標を ゲームサーバ
サーバに通知
① 移動先を
クリック
ユーザA ユーザB
12年10月4日木曜日 12
- 13. リアルタイム通信が出来る
② 移動先座標を ゲームサーバ
サーバに通知
③ 即座に、移動先の
座標を他の
クライアントに通知
① 移動先を
クリック
ユーザA ユーザB
12年10月4日木曜日 13
- 18. 『三国志コンクエスト』
Unityで開発したオンラインゲーム
SLG+ACTを融合。ACTはリアルタイム方式
12年10月4日木曜日 18
- 21. これまでのオンラインゲームは、直接
TCP/IPを使っていた(場合が多い)
TCP/IPで直接通信するのと、
WebSocketで通信することの違いは?
12年10月4日木曜日 21
- 26. WebSocketのメリット
1.既存インフラへの影響の少なさ
2.メッセージ単位の送受信
3.暗号化
12年10月4日木曜日 26
- 28. 既存インフラへの影響の少なさ
TCP/IPでは、他のプロセスが使っていない専用のポー
ト番号で通信を行う場合が多い(35000番ポート等)
12年10月4日木曜日 28
- 29. 既存インフラへの影響の少なさ
TCP/IPでは、他のプロセスが使っていない専用のポー
ト番号で通信を行う場合が多い(35000番ポート等)
WebSocketサーバは、Webサーバが兼任する場合が多
く、セッション接続にHTTPを利用するため、80/443
番ポートでそのまま接続できる
12年10月4日木曜日 29
- 30. 既存インフラへの影響の少なさ
ゲームサーバ
TCP/IPを直接
使う場合、専用
の通信を行うた
めの穴を開ける
必要があった
クライアント
12年10月4日木曜日 30
- 31. 既存インフラへの影響の少なさ
ゲームサーバ
TCP/IPを直接
使う場合、専用
の通信を行うた
めの穴を開ける
game.server.com:35000
に接続
必要があった
クライアント
12年10月4日木曜日 31
- 32. 既存インフラへの影響の少なさ
ゲームサーバ
TCP/IPを直接
使う場合、専用
の通信を行うた 35000番ポートへの
アクセス許可
めの穴を開ける
game.server.com:35000
に接続
必要があった
クライアント
12年10月4日木曜日 32
- 33. 既存インフラへの影響の少なさ
ゲームサーバ
TCP/IPを直接 35000番ポートへのア
クセスをサーバに
フォワード
使う場合、専用
の通信を行うた 35000番ポートへの
アクセス許可
めの穴を開ける
game.server.com:35000
に接続
必要があった
クライアント
12年10月4日木曜日 33
- 34. 既存インフラへの影響の少なさ
ゲームサーバ
WebSocketは、
HTTPが使える環
境であればそのま
ま利用出来る(プ
ロキシを通過する
ことも可能)
クライアント
12年10月4日木曜日 34
- 35. 既存インフラへの影響の少なさ
ゲームサーバ
WebSocketは、
HTTPが使える環
境であればそのま
ま利用出来る(プ
ロキシを通過する ws://game.server.com/wsurl/
に接続
ことも可能)
クライアント
12年10月4日木曜日 35
- 36. 既存インフラへの影響の少なさ
ゲームサーバ
WebSocketは、
HTTPが使える環
境であればそのま
80番ポートへの
ま利用出来る(プ HTTPアクセス
ロキシを通過する ws://game.server.com/wsurl/
に接続
ことも可能)
クライアント
12年10月4日木曜日 36
- 37. 既存インフラへの影響の少なさ
ゲームサーバ
WebSocketは、
80番ポートの
WebSocketへの
HTTPが使える環 アクセスをサーバに
フォワード
境であればそのま
80番ポートへの
ま利用出来る(プ HTTPアクセス
ロキシを通過する ws://game.server.com/wsurl/
に接続
ことも可能)
クライアント
12年10月4日木曜日 37
- 39. メッセージ単位の送受信
TCP/IPでは、独自のプロトコル仕様を定義し、
送受信処理を実装していた
12年10月4日木曜日 39
- 40. メッセージ単位の送受信
TCP/IPでは、独自のプロトコル仕様を定義し、
送受信処理を実装していた
WebSocketではメッセージ単位の送受信が規定
されており、メッセージを構成する部分はライブ
ラリ側で実装される
12年10月4日木曜日 40
- 41. メッセージ単位の送受信
メッセージID データサイズ データ本体
2byte 2byte XXbyte
ソースコード例
for( ; ; ) {
short messageId = stream.readShort();
short dataSize = stream.readShort();
byte[] data = new byte[dataSize];
int readSize = 0;
while( true ) { // ★ データの読み込みが完了するまでループ
readSize += stream.read( data, readSize, dataSize - readSize );
if( readSize >= dataSize ) {
break;
}
}
execute( messageId, data );
}
12年10月4日木曜日 41
- 42. メッセージ単位の送受信
サーバ・クライアントの双方で実装する必要がある。
エラー処理も必要。
12年10月4日木曜日 42
- 43. メッセージ単位の送受信
サーバ・クライアントの双方で実装する必要がある。
エラー処理も必要。
サーバでは多くのクライアントが接続されるため、負
荷対策やメモリ管理も必要となる。
12年10月4日木曜日 43
- 44. メッセージ単位の送受信
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len | Extended payload length |
|I|S|S|S| (4) |A| (7) | (16/64) |
|N|V|V|V| |S| | (if payload len==126/127) |
| |1|2|3| |K| | |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
| Extended payload length continued, if payload len == 127 |
+ - - - - - - - - - - - - - - - +-------------------------------+
| |Masking-key, if MASK set to 1 |
+-------------------------------+-------------------------------+
| Masking-key (continued) | Payload Data |
+-------------------------------- - - - - - - - - - - - - - - - +
: Payload Data continued ... :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Payload Data continued ... |
+---------------------------------------------------------------+
WebSocketでは、テキスト or バイナリ形式の
データの送受信がプロトコルとして規定されている
12年10月4日木曜日 44
- 45. メッセージ単位の送受信
ソースコード例
// bytebufferが受信データそのもの
protected void onBinaryMessage(ByteBuffer bytebuffer)
throws IOException {
short messageId = bytebuffer.getShort();
execute(messageId, bytebuffer);
}
データ受信処理が大幅に簡略化される
12年10月4日木曜日 45
- 47. 暗号化
HTTPと同様に、WebSocketの暗号化も
プロトコルとして規定されている
12年10月4日木曜日 47
- 48. 暗号化
HTTPと同様に、WebSocketの暗号化も
プロトコルとして規定されている
http:// => https://
ws:// => wss://
12年10月4日木曜日 48
- 49. 暗号化
HTTPと同様に、WebSocketの暗号化も
プロトコルとして規定されている
http:// => https://
ws:// => wss://
デフォルトポート番号
80 => 443
12年10月4日木曜日 49
- 51. WebSocketのメリット
既存インフラへの影響の少なさ
メッセージ単位の送受信
暗号化
これらは、HTTPの特徴でもある
12年10月4日木曜日 51
- 52. WebSocketのメリット
つまり、TCP/IPの軽量な双方向通信と、
HTTPの利便性の両方のメリットを持つ。
12年10月4日木曜日 52
- 53. WebSocketのメリット
つまり、TCP/IPの軽量な双方向通信と、
HTTPの利便性の両方のメリットを持つ。
これらは既存でも実現できていたが、非常に
面倒であり、相応の技術力を要していた。
12年10月4日木曜日 53
- 54. WebSocketのメリット
つまり、TCP/IPの軽量な双方向通信と、
HTTPの利便性の両方のメリットを持つ。
これらは既存でも実現できていたが、非常に
面倒であり、相応の技術力を要していた。
=> オンラインゲームの通信部分の
開発のハードルが大幅に下がった
12年10月4日木曜日 54
- 57. WebSocketのデメリット
現状、考えられるデメリットは2つ。
1.Request - Response形式が無い
12年10月4日木曜日 57
- 58. WebSocketのデメリット
現状、考えられるデメリットは2つ。
1.Request - Response形式が無い
2.実績が少ない
12年10月4日木曜日 58
- 59. Request - Response形式が無い
WebSocketでは一方向のメッセージの定
義しか無いため、Request - Response
形式のメッセージの送受信を行う場合
は、独自に実装が必要。
12年10月4日木曜日 59
- 60. 実績が少ない
2011年12月:RFC6455規定
2012年01月:Jetty対応
2012年02月:node.js対応
2012年03月:Tomcat対応(テスト実装)
2012年06月:UniWeb対応
動作実績は、せいぜい半年程度
12年10月4日木曜日 60
- 62. デモに至るまで・・・
Tomcat7.0.27�+ Google Chrome => OK
12年10月4日木曜日 62
- 63. デモに至るまで・・・
Tomcat7.0.27�+ Google Chrome => OK
Tomcat7.0.27�+ Unity(websocket-sharp)
=> プロトコルバージョン不一致により通信不可
12年10月4日木曜日 63
- 64. デモに至るまで・・・
Tomcat7.0.27�+ Google Chrome => OK
Tomcat7.0.27�+ Unity(websocket-sharp)
=> プロトコルバージョン不一致により通信不可
Tomcat7.0.27�+ Unity(SuperWebSocket)
=> SuperWebSocket動作せず(VisualStudioだとOK)
12年10月4日木曜日 64
- 65. デモに至るまで・・・
Tomcat7.0.27�+ Google Chrome => OK
Tomcat7.0.27�+ Unity(websocket-sharp)
=> プロトコルバージョン不一致により通信不可
Tomcat7.0.27�+ Unity(SuperWebSocket)
=> SuperWebSocket動作せず(VisualStudioだとOK)
Jetty8.1.3�+ Unity(websocket-sharp)
=> OKだがプロトコルバージョンが古い
12年10月4日木曜日 65
- 66. デモに至るまで・・・
Tomcat7.0.27�+ Google Chrome => OK
Tomcat7.0.27�+ Unity(websocket-sharp)
=> プロトコルバージョン不一致により通信不可
Tomcat7.0.27�+ Unity(SuperWebSocket)
=> SuperWebSocket動作せず(VisualStudioだとOK)
Jetty8.1.3�+ Unity(websocket-sharp)
=> OKだがプロトコルバージョンが古い
Tomcat7.0.27�+ Unity(UniWeb)
=> いずれかのバグにより動作不可
12年10月4日木曜日 66
- 67. デモに至るまで・・・
UniWebの以下の箇所を修正したら、うまく動いた!
Response.cs
171 cacheable = string.Compare (GetHeader ("Etag"), "", true) != 0;
172 chunked = string.Compare (GetHeader ("Transfer-Encoding"), "chunked", true) == 0;
173 zipped = string.Compare (GetHeader ("Content-Encoding"), "gzip", true) == 0;
174 byte[] buffer = new byte[1024];
175 chunked = false; // ★★★ この行を挿入 ★★★
176
177
178
if (chunked) {
while (true) {
Response.cs
175: chunked = false;
179 // Collect Body
180 var hexLength = ReadLine (inputStream);
12年10月4日木曜日 67
- 68. デモに至るまで・・・
UniWebの以下の箇所を修正したら、うまく動いた!
Response.cs
171 cacheable = string.Compare (GetHeader ("Etag"), "", true) != 0;
172 chunked = string.Compare (GetHeader ("Transfer-Encoding"), "chunked", true) == 0;
173 zipped = string.Compare (GetHeader ("Content-Encoding"), "gzip", true) == 0;
174 byte[] buffer = new byte[1024];
175 chunked = false; // ★★★ この行を挿入 ★★★
176
177
178
if (chunked) {
while (true) {
Response.cs
175: chunked = false;
179 // Collect Body
180 var hexLength = ReadLine (inputStream);
まだまだ現時点ではイバラの道
12年10月4日木曜日 68
- 69. まとめ
現時点では実績の少ないWebSocketだが、オンライ
ンゲームを作る上での有用性には確信が持てる
(RFC6455にも、「ゲームでも使える」との記述が
ある)
今後、オンラインゲームはWebSocketで作るのが当
たり前、という時代が来る!かも知れない・・・
12年10月4日木曜日 69
- 73. デモに至るまで・・・
TomcatがWebSocketを実装した!?
=> Tomcat7.0.27(3/31リリース)インストール
=> Google Chromeでチャットの動作確認!
12年10月4日木曜日 73
- 74. デモに至るまで・・・
TomcatがWebSocketを実装した!?
=> Tomcat7.0.27(3/31リリース)インストール
=> Google Chromeでチャットの動作確認!
Unityをクライアントにしよう!
=> Unity + websocket-sharp を使う
=> バージョン不一致で接続不可
websocket-sharpの更新が1年以上停止していた
12年10月4日木曜日 74
- 75. デモに至るまで・・・
他のC#の実装を探す
=> SuperWebSocketというのがあるらしい
=> Unityに組み込もうと悪戦苦闘
=> VisualStudioでは動くがUnityでは動かず
=> 技術不足により断念
12年10月4日木曜日 75
- 76. デモに至るまで・・・
他のC#の実装を探す
=> SuperWebSocketというのがあるらしい
=> Unityに組み込もうと悪戦苦闘
=> VisualStudioでは動くがUnityでは動かず
=> 技術不足により断念
Tomcatを諦めてJettyを試す
=> 慣れないJettyに戸惑いつつも単体動作完了
=> Unity + websocket-sharp とJettyとの通信成功
=> 但し、RFC6455ではないのでちょっとモヤモヤ
(websocket-sharpが古いため)
12年10月4日木曜日 76
- 77. デモに至るまで・・・
UnityのAssetであるUniWebが、WebSocketをサポー
トしたらしい!
=> Tomcat7.0.27 + Unity3.5.2 + UniWebを試す
=> 接続には失敗する・・・が、リクエストは通っており、レ
スポンスでエラーとなっているらしい
12年10月4日木曜日 77
- 78. デモに至るまで・・・
UnityのAssetであるUniWebが、WebSocketをサポー
トしたらしい!
=> Tomcat7.0.27 + Unity3.5.2 + UniWebを試す
=> 接続には失敗する・・・が、リクエストは通っており、レ
スポンスでエラーとなっているらしい
Tomcat + UniWebの通信データを解析
=> レスポンスの認識違いによるエラーと判明
=> 多分Tomcatが悪い・・・が、Tomcatの手直しは難し
いので、UniWeb側を修正
12年10月4日木曜日 78