Unity + WebSocketで広がる

              オンラインゲームの可能性

                  株式会社セガ

                   上原光晶


12年10月4日木曜日                       1
Contents

              WebSocketの紹介

              WebSocketを使ったデモ(ブラウザ・Unity)

              WebSocketのメリット・デメリット

              まとめ




12年10月4日木曜日                                 2
自己紹介
              2006年にシステム屋からアプリ開発者に

              2008年頃から、携帯電話向けオンラインゲー

              ムの主にサーバを担当(iアプリ)

              2012年2月にセガへ転職し、現在はUnityを

              使ったスマートフォン向けオンラインゲームを

              開発中


12年10月4日木曜日                              3
WebSocketとは?


12年10月4日木曜日                  4
WebSocketとは
              コンピュータ・ネットワーク用の通信規格の1
              つ。W3CとIETFがウェブサーバーとウェブブ
              ラウザとの間の通信のために規定を予定して
              いる双方向通信用の技術規格であり、APIは
              W3Cが、WebSocket プロトコルはIETFが策定
              に関与している。プロトコルの仕様は RFC
              6455。TCP上で動く。(Wikipediaより引用)


12年10月4日木曜日                                  5
何が出来るのか?


12年10月4日木曜日              6
ブラウザ上でのデモ



12年10月4日木曜日           7
Unity + WebSocket
              で何が出来るのか

12年10月4日木曜日                   8
Unity + WebSocketのデモ




12年10月4日木曜日                     9
リアルタイム通信が出来る
                     ゲームサーバ

                        WebSocketの
                         コネクション




              ユーザA    ユーザB

12年10月4日木曜日                          10
リアルタイム通信が出来る
                       ゲームサーバ




       ① 移動先を
        クリック




                ユーザA    ユーザB

12年10月4日木曜日                     11
リアルタイム通信が出来る
     ② 移動先座標を          ゲームサーバ
      サーバに通知



       ① 移動先を
        クリック




                ユーザA    ユーザB

12年10月4日木曜日                     12
リアルタイム通信が出来る
     ② 移動先座標を          ゲームサーバ
      サーバに通知
                          ③ 即座に、移動先の
                             座標を他の
                           クライアントに通知
       ① 移動先を
        クリック




                ユーザA    ユーザB

12年10月4日木曜日                            13
Unity + WebSocketで、リアルタイムの

          オンラインゲームが作れるようになる!




12年10月4日木曜日                                14
Unity + WebSocketで、リアルタイムの

          オンラインゲームが作れるようになる!

               とは言え、これまでも数多く、

              リアルタイムのオンラインゲームが

                      存在していた


12年10月4日木曜日                                15
UO(ウルティマオンライン)や

          MHF(モンハンフロンティア)、

              最近ではDiabloIIIなんてのも出た



12年10月4日木曜日                          16
『ファンタシースターオンライン2』

                本日正式サービス開始!
12年10月4日木曜日                       17
『三国志コンクエスト』

                Unityで開発したオンラインゲーム

              SLG+ACTを融合。ACTはリアルタイム方式

12年10月4日木曜日                             18
これまでと何が違うのか



12年10月4日木曜日             19
これまでのオンラインゲームは、直接

              TCP/IPを使っていた(場合が多い)




12年10月4日木曜日                         20
これまでのオンラインゲームは、直接

              TCP/IPを使っていた(場合が多い)


               TCP/IPで直接通信するのと、

          WebSocketで通信することの違いは?



12年10月4日木曜日                         21
WebSocketには、TCP/IPを直接使うこ

          とに対して3つのメリットが発生する。




12年10月4日木曜日                              22
WebSocketのメリット




12年10月4日木曜日                    23
WebSocketのメリット

              1.既存インフラへの影響の少なさ




12年10月4日木曜日                      24
WebSocketのメリット

              1.既存インフラへの影響の少なさ

              2.メッセージ単位の送受信




12年10月4日木曜日                      25
WebSocketのメリット

              1.既存インフラへの影響の少なさ

              2.メッセージ単位の送受信

              3.暗号化




12年10月4日木曜日                      26
既存インフラへの影響の少なさ




12年10月4日木曜日                27
既存インフラへの影響の少なさ

        TCP/IPでは、他のプロセスが使っていない専用のポー

        ト番号で通信を行う場合が多い(35000番ポート等)




12年10月4日木曜日                           28
既存インフラへの影響の少なさ

        TCP/IPでは、他のプロセスが使っていない専用のポー

        ト番号で通信を行う場合が多い(35000番ポート等)


        WebSocketサーバは、Webサーバが兼任する場合が多

        く、セッション接続にHTTPを利用するため、80/443

        番ポートでそのまま接続できる



12年10月4日木曜日                             29
既存インフラへの影響の少なさ
                              ゲームサーバ
              TCP/IPを直接

              使う場合、専用

              の通信を行うた

              めの穴を開ける

              必要があった
                          クライアント
12年10月4日木曜日                            30
既存インフラへの影響の少なさ
                               ゲームサーバ
              TCP/IPを直接

              使う場合、専用

              の通信を行うた

              めの穴を開ける
                            game.server.com:35000
                                    に接続
              必要があった
                          クライアント
12年10月4日木曜日                                         31
既存インフラへの影響の少なさ
                               ゲームサーバ
              TCP/IPを直接

              使う場合、専用

              の通信を行うた             35000番ポートへの
                                    アクセス許可

              めの穴を開ける
                            game.server.com:35000
                                    に接続
              必要があった
                          クライアント
12年10月4日木曜日                                         32
既存インフラへの影響の少なさ
                               ゲームサーバ
              TCP/IPを直接           35000番ポートへのア
                                    クセスをサーバに
                                      フォワード

              使う場合、専用

              の通信を行うた             35000番ポートへの
                                    アクセス許可

              めの穴を開ける
                            game.server.com:35000
                                    に接続
              必要があった
                          クライアント
12年10月4日木曜日                                         33
既存インフラへの影響の少なさ
                                ゲームサーバ
              WebSocketは、

              HTTPが使える環

              境であればそのま

              ま利用出来る(プ

              ロキシを通過する

              ことも可能)
                            クライアント
12年10月4日木曜日                              34
既存インフラへの影響の少なさ
                                   ゲームサーバ
              WebSocketは、

              HTTPが使える環

              境であればそのま

              ま利用出来る(プ

              ロキシを通過する       ws://game.server.com/wsurl/
                                       に接続
              ことも可能)
                            クライアント
12年10月4日木曜日                                            35
既存インフラへの影響の少なさ
                                   ゲームサーバ
              WebSocketは、

              HTTPが使える環

              境であればそのま
                                         80番ポートへの
              ま利用出来る(プ                    HTTPアクセス



              ロキシを通過する       ws://game.server.com/wsurl/
                                       に接続
              ことも可能)
                            クライアント
12年10月4日木曜日                                            36
既存インフラへの影響の少なさ
                                   ゲームサーバ
              WebSocketは、
                                         80番ポートの
                                        WebSocketへの
              HTTPが使える環                 アクセスをサーバに
                                          フォワード


              境であればそのま
                                         80番ポートへの
              ま利用出来る(プ                    HTTPアクセス



              ロキシを通過する       ws://game.server.com/wsurl/
                                       に接続
              ことも可能)
                            クライアント
12年10月4日木曜日                                            37
メッセージ単位の送受信



12年10月4日木曜日             38
メッセージ単位の送受信
              TCP/IPでは、独自のプロトコル仕様を定義し、

              送受信処理を実装していた




12年10月4日木曜日                              39
メッセージ単位の送受信
              TCP/IPでは、独自のプロトコル仕様を定義し、

              送受信処理を実装していた


              WebSocketではメッセージ単位の送受信が規定

              されており、メッセージを構成する部分はライブ

              ラリ側で実装される



12年10月4日木曜日                               40
メッセージ単位の送受信
              メッセージ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
メッセージ単位の送受信
       サーバ・クライアントの双方で実装する必要がある。

       エラー処理も必要。




12年10月4日木曜日                       42
メッセージ単位の送受信
       サーバ・クライアントの双方で実装する必要がある。

       エラー処理も必要。


       サーバでは多くのクライアントが接続されるため、負

       荷対策やメモリ管理も必要となる。




12年10月4日木曜日                       43
メッセージ単位の送受信
              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
メッセージ単位の送受信
      ソースコード例
        // bytebufferが受信データそのもの
        protected void onBinaryMessage(ByteBuffer bytebuffer)
          throws IOException {
            short messageId = bytebuffer.getShort();
            execute(messageId, bytebuffer);
        }




        データ受信処理が大幅に簡略化される

12年10月4日木曜日                                                     45
暗号化


12年10月4日木曜日         46
暗号化
        HTTPと同様に、WebSocketの暗号化も
        プロトコルとして規定されている




12年10月4日木曜日                       47
暗号化
        HTTPと同様に、WebSocketの暗号化も
        プロトコルとして規定されている

                http:// => https://
                 ws:// => wss://




12年10月4日木曜日                           48
暗号化
        HTTPと同様に、WebSocketの暗号化も
        プロトコルとして規定されている

                http:// => https://
                 ws:// => wss://

                デフォルトポート番号
                  80 => 443

12年10月4日木曜日                           49
WebSocketのメリット

              既存インフラへの影響の少なさ

              メッセージ単位の送受信

              暗号化




12年10月4日木曜日                    50
WebSocketのメリット

              既存インフラへの影響の少なさ

              メッセージ単位の送受信

              暗号化

              これらは、HTTPの特徴でもある

12年10月4日木曜日                      51
WebSocketのメリット
          つまり、TCP/IPの軽量な双方向通信と、

         HTTPの利便性の両方のメリットを持つ。




12年10月4日木曜日                       52
WebSocketのメリット
          つまり、TCP/IPの軽量な双方向通信と、

         HTTPの利便性の両方のメリットを持つ。

          これらは既存でも実現できていたが、非常に

         面倒であり、相応の技術力を要していた。




12年10月4日木曜日                       53
WebSocketのメリット
          つまり、TCP/IPの軽量な双方向通信と、

         HTTPの利便性の両方のメリットを持つ。

          これらは既存でも実現できていたが、非常に

         面倒であり、相応の技術力を要していた。

         => オンラインゲームの通信部分の

              開発のハードルが大幅に下がった
12年10月4日木曜日                       54
一方、デメリットは無いのか




12年10月4日木曜日               55
WebSocketのデメリット
          現状、考えられるデメリットは2つ。




12年10月4日木曜日                     56
WebSocketのデメリット
          現状、考えられるデメリットは2つ。


         1.Request - Response形式が無い




12年10月4日木曜日                          57
WebSocketのデメリット
          現状、考えられるデメリットは2つ。


         1.Request - Response形式が無い

         2.実績が少ない



12年10月4日木曜日                          58
Request - Response形式が無い

         WebSocketでは一方向のメッセージの定

         義しか無いため、Request - Response

         形式のメッセージの送受信を行う場合

         は、独自に実装が必要。



12年10月4日木曜日                             59
実績が少ない
       2011年12月:RFC6455規定
       2012年01月:Jetty対応
       2012年02月:node.js対応
       2012年03月:Tomcat対応(テスト実装)
       2012年06月:UniWeb対応

              動作実績は、せいぜい半年程度

12年10月4日木曜日                       60
デモに至るまで・・・




12年10月4日木曜日                61
デモに至るまで・・・
       Tomcat7.0.27�+ Google Chrome => OK




12年10月4日木曜日                                 62
デモに至るまで・・・
       Tomcat7.0.27�+ Google Chrome => OK
       Tomcat7.0.27�+ Unity(websocket-sharp)
       => プロトコルバージョン不一致により通信不可




12年10月4日木曜日                                    63
デモに至るまで・・・
       Tomcat7.0.27�+ Google Chrome => OK
       Tomcat7.0.27�+ Unity(websocket-sharp)
       => プロトコルバージョン不一致により通信不可
       Tomcat7.0.27�+ Unity(SuperWebSocket)
       => SuperWebSocket動作せず(VisualStudioだとOK)




12年10月4日木曜日                                      64
デモに至るまで・・・
       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
デモに至るまで・・・
       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
デモに至るまで・・・
       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
デモに至るまで・・・
       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
まとめ
        現時点では実績の少ないWebSocketだが、オンライ

        ンゲームを作る上での有用性には確信が持てる

        (RFC6455にも、「ゲームでも使える」との記述が

        ある)


        今後、オンラインゲームはWebSocketで作るのが当

        たり前、という時代が来る!かも知れない・・・


12年10月4日木曜日                           69
Unity + WebSocketで、オンライン

              ゲームの新しい時代を切り拓け!!




12年10月4日木曜日                              70
ご清聴、ありがとうございました。




12年10月4日木曜日                  71
デモに至るまで・・・




12年10月4日木曜日                72
デモに至るまで・・・
       TomcatがWebSocketを実装した!?
       => Tomcat7.0.27(3/31リリース)インストール
       => Google Chromeでチャットの動作確認!




12年10月4日木曜日                              73
デモに至るまで・・・
       TomcatがWebSocketを実装した!?
       => Tomcat7.0.27(3/31リリース)インストール
       => Google Chromeでチャットの動作確認!


       Unityをクライアントにしよう!
       => Unity + websocket-sharp を使う
       => バージョン不一致で接続不可
        websocket-sharpの更新が1年以上停止していた


12年10月4日木曜日                              74
デモに至るまで・・・
       他のC#の実装を探す
       => SuperWebSocketというのがあるらしい
       => Unityに組み込もうと悪戦苦闘
       => VisualStudioでは動くがUnityでは動かず
       => 技術不足により断念




12年10月4日木曜日                             75
デモに至るまで・・・
       他のC#の実装を探す
       => SuperWebSocketというのがあるらしい
       => Unityに組み込もうと悪戦苦闘
       => VisualStudioでは動くがUnityでは動かず
       => 技術不足により断念

       Tomcatを諦めてJettyを試す
       => 慣れないJettyに戸惑いつつも単体動作完了
       => Unity + websocket-sharp とJettyとの通信成功
       => 但し、RFC6455ではないのでちょっとモヤモヤ
         (websocket-sharpが古いため)

12年10月4日木曜日                                      76
デモに至るまで・・・
       UnityのAssetであるUniWebが、WebSocketをサポー
       トしたらしい!
       => Tomcat7.0.27 + Unity3.5.2 + UniWebを試す
       => 接続には失敗する・・・が、リクエストは通っており、レ
       スポンスでエラーとなっているらしい




12年10月4日木曜日                                       77
デモに至るまで・・・
       UnityのAssetであるUniWebが、WebSocketをサポー
       トしたらしい!
       => Tomcat7.0.27 + Unity3.5.2 + UniWebを試す
       => 接続には失敗する・・・が、リクエストは通っており、レ
       スポンスでエラーとなっているらしい

       Tomcat + UniWebの通信データを解析
       => レスポンスの認識違いによるエラーと判明
       => 多分Tomcatが悪い・・・が、Tomcatの手直しは難し
       いので、UniWeb側を修正

12年10月4日木曜日                                       78

Unity WebSocket

  • 1.
    Unity + WebSocketで広がる オンラインゲームの可能性 株式会社セガ 上原光晶 12年10月4日木曜日 1
  • 2.
    Contents WebSocketの紹介 WebSocketを使ったデモ(ブラウザ・Unity) WebSocketのメリット・デメリット まとめ 12年10月4日木曜日 2
  • 3.
    自己紹介 2006年にシステム屋からアプリ開発者に 2008年頃から、携帯電話向けオンラインゲー ムの主にサーバを担当(iアプリ) 2012年2月にセガへ転職し、現在はUnityを 使ったスマートフォン向けオンラインゲームを 開発中 12年10月4日木曜日 3
  • 4.
  • 5.
    WebSocketとは コンピュータ・ネットワーク用の通信規格の1 つ。W3CとIETFがウェブサーバーとウェブブ ラウザとの間の通信のために規定を予定して いる双方向通信用の技術規格であり、APIは W3Cが、WebSocket プロトコルはIETFが策定 に関与している。プロトコルの仕様は RFC 6455。TCP上で動く。(Wikipediaより引用) 12年10月4日木曜日 5
  • 6.
  • 7.
  • 8.
    Unity + WebSocket で何が出来るのか 12年10月4日木曜日 8
  • 9.
  • 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
  • 14.
    Unity + WebSocketで、リアルタイムの オンラインゲームが作れるようになる! 12年10月4日木曜日 14
  • 15.
    Unity + WebSocketで、リアルタイムの オンラインゲームが作れるようになる! とは言え、これまでも数多く、 リアルタイムのオンラインゲームが 存在していた 12年10月4日木曜日 15
  • 16.
    UO(ウルティマオンライン)や MHF(モンハンフロンティア)、 最近ではDiabloIIIなんてのも出た 12年10月4日木曜日 16
  • 17.
    『ファンタシースターオンライン2』 本日正式サービス開始! 12年10月4日木曜日 17
  • 18.
    『三国志コンクエスト』 Unityで開発したオンラインゲーム SLG+ACTを融合。ACTはリアルタイム方式 12年10月4日木曜日 18
  • 19.
  • 20.
    これまでのオンラインゲームは、直接 TCP/IPを使っていた(場合が多い) 12年10月4日木曜日 20
  • 21.
    これまでのオンラインゲームは、直接 TCP/IPを使っていた(場合が多い) TCP/IPで直接通信するのと、 WebSocketで通信することの違いは? 12年10月4日木曜日 21
  • 22.
    WebSocketには、TCP/IPを直接使うこ とに対して3つのメリットが発生する。 12年10月4日木曜日 22
  • 23.
  • 24.
    WebSocketのメリット 1.既存インフラへの影響の少なさ 12年10月4日木曜日 24
  • 25.
    WebSocketのメリット 1.既存インフラへの影響の少なさ 2.メッセージ単位の送受信 12年10月4日木曜日 25
  • 26.
    WebSocketのメリット 1.既存インフラへの影響の少なさ 2.メッセージ単位の送受信 3.暗号化 12年10月4日木曜日 26
  • 27.
  • 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
  • 38.
  • 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
  • 46.
  • 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
  • 50.
    WebSocketのメリット 既存インフラへの影響の少なさ メッセージ単位の送受信 暗号化 12年10月4日木曜日 50
  • 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
  • 55.
  • 56.
    WebSocketのデメリット 現状、考えられるデメリットは2つ。 12年10月4日木曜日 56
  • 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
  • 61.
  • 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
  • 70.
    Unity + WebSocketで、オンライン ゲームの新しい時代を切り拓け!! 12年10月4日木曜日 70
  • 71.
  • 72.
  • 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