SlideShare a Scribd company logo
1 of 37
アメーバピグのサーバと クライアントは どうやって通信しているのか
アジェンダ ・自己紹介 ・アメーバピグとは ・アメーバピグのシステムアーキテクチャ ・クライアントとサーバ間の通信方法   ・  CommandID での通信   ・  MethodName での通信 ・まとめ
自己紹介
田中 広海 ( たなひろ ) 株式会社サイバーエージェント アメーバ事業本部所属 2010 年 2 月中途入社 Twitter : @tn_hiro 職歴:ゲーム会社、携帯コンテンツ開発 趣味:ガッツリいろいろと・・・
アメーバピグとは
仮想空間上で自分にそっくりなアバター(ピグ)を作り ユーザ同士でコミュニケーションがとれるサービス
システムアーキテクチャ
HadoopCluster FileStorage Database Game Server Chat Server Info Server Web Server
HadoopCluster FileStorage Database Game Server Chat Server Info Server Web Server Hadoop ユーザ行動 Log
HadoopCluster FileStorage Database Game Server Chat Server Info Server Web Server Isilon 商用分散 storage
HadoopCluster FileStorage Database Game Server Chat Server Info Server Web Server MySql + FusionIO + Memcached
HadoopCluster FileStorage Database Game Server Chat Server Info Server Web Server Flash,Image を配信
HadoopCluster FileStorage Database Game Server Chat Server Info Server Web Server ユーザ情報の通信
HadoopCluster FileStorage Database Game Server Chat Server Info Server Web Server チャットデータ エリア情報の通信
HadoopCluster FileStorage Database Game Server Chat Server Info Server Web Server ChatServer + ゲーム情報の通信
クライアントとサーバ間の 通信方法
サーバ Java Application java.net.Socket を使用 クライアント Flash(ActionScript3.0) flash.net.Socket を使用
CommandId を使用しての通信
ピグで chat を行うときの流れで説明する ユーザが TextArea に入力
Flash (クライアント) 側 から Java( サーバ ) への送信 public static const TALK:int = 0x0000; public function writeData(bytes:ByteArray):void   var bytes:ByteArray = new ByteArray()   bytes.writeByte(TALK);   bytes.writeUTF(message);   bytes.writeUnsignedInt(color); }
Java( サーバ ) で受信 public static final short TALK = 0x0000; public class TalkData implements CommandData{   public void readData(ByteBuilder in) {    byte commandId = in.getByte();    String message = in.getUTF();    int color = in.getInt();      talk(user, message, color);   } }
同一エリア内のユーザに配信 public void talk(ChatUser user, String message, int color)    throws ServiceException {   //  今いるエリアを取得   ChatArea chatArea = user.getChatArea();   //  話した内容を Data(Command) 化   TalkResultData talkResult = new TalkResultData(user.getAmebaId(),                         user.getNickname(),                         message,                         color);   // broadcast   for (ChatUser user : chatArea.getUsers()) {    CommandConnection conn = user.getConnection();    conn.sendCommand(talkResult);   } }
public static final short TALK_RESULT = 0x0001; public class TalkResultData implements CommandData{   public TalkResultData(String amebaId, String nickname,             String message, int color) {    this.commandId = CommandId.TALK_RESULT;    this.amebaId = Binaries.toBytes(amebaId);    this.nickname = Binaries.toBytes(nickname);    this.messageByte = Binaries.toBytes(message);    this.color = color;   }   // Java( サーバ )  側 から Flash (クライアント) への送信   public void writeData(ByteBuilder out) {    out.put Byte  (commandId);    out.putShort((short)messageByte.length);    out.put(messageByte);    out.putInt(color);    out.putShort((short)amebaId.length);    out.put(amebaId);    out.putShort((short)nickname.length);    out.put(nickname);   } }
Flash (クライアント) の 受信 public static const TALK_RESULT:int = 0x0001;  public function readData(bytes:ByteArray):void {   commandId = bytes.readUnsignedByte();   message = bytes.readUTF();   color = bytes.readUnsignedInt();   amebaId = bytes.readUTF();   nickname = bytes.readUTF(); } public function talk(msg:String, color:uint):void   _chat.addBubble(new ChatBubble(msg, color)); }
Flash (クライアント) の 受信 public static const TALK_RESULT:int = 0x0001;  public function readData(bytes:ByteArray):void {   commandId = bytes.readUnsignedByte();   message = bytes.readUTF();   color = bytes.readUnsignedInt();   amebaId = bytes.readUTF();   nickname = bytes.readUTF(); } public function talk(msg:String, color:uint):void   _chat.addBubble(new ChatBubble(msg, color)); }
CommandId での分岐
TALK 0x0000 TALK_RESULT 0x0001 MOVE 0x0002 MOVE_RESULT 0x0003
TALK 0x0000 MOVE 0x0002 switch (commandId) {   case TALK:    talk();    break;   case MOVE:    move();    break; }
CommandId での問題点
・ ID を割り振るのはメンドクサイ   Java 側と Flash 側で同じ番号を振らないといけない ・ 直接番号を振っているので、   0x000F と 0x0010 の間に   別のコマンドを足したいと思っても足せない  ・ ID と実行メソッドの関連付けのために   switch 文の修正が必要
・ ID を割り振るのはメンドクサイ   Java 側と Flash 側で同じ番号を振らないといけない ・ 直接番号を振っているので、   0x000F と 0x0010 の間に   別のコマンドを足したいと思っても足せない  ・ ID と実行メソッドの関連付けのために   switch 文の修正が必要  ↓  MethodName での Command 呼び出しが 実装されました!
MethodName での分岐
Flash 送信 部 public function writeData(bytes:ByteArray):void   var bytes:ByteArray = new ByteArray()   bytes.putUTFNullEmpty(&quot;talk&quot;);   bytes.writeByte(CommandId.TALK);   bytes.writeUTF(message);   bytes.writeUnsignedInt(color); } Java 側 分岐 private Map<String, Method> serviceMethods; Method method = serviceMethods.get( methodName ); method.invoke();
MethodName での問題点
・ Flash 側で設定した MethodName によって、   サーバ側が分岐する ・ Java 側のソースだけだと、   どの Method がいつ呼ばれるかわからない。  ・ CommandId 仕様であれば、   (CommandId の宣 言部分が一 ヶ所に固まっているので )    処理部を検索する時にも grep 出来て楽だった。
まとめ ・ commandId での方法も、 MethodName での方法も   一長一短   新規で機能を実装するなら、 MethodName の方が   コードを書く量が少なくて楽 ・ 速度重視の開発という意味では、 MethodName おすすめ ・ 後でまったく知らない人がソース読むときには大変かも
ご清聴ありがとうございました

More Related Content

Viewers also liked

Matrix Factorizationを使った評価予測
Matrix Factorizationを使った評価予測Matrix Factorizationを使った評価予測
Matrix Factorizationを使った評価予測JAVA DM
 
OpenCVによる顔認識システムの開発
OpenCVによる顔認識システムの開発OpenCVによる顔認識システムの開発
OpenCVによる顔認識システムの開発Takahiko Teramoto
 
松本克彦 ピグにおけるリアルタイムランキングの導入
松本克彦 ピグにおけるリアルタイムランキングの導入松本克彦 ピグにおけるリアルタイムランキングの導入
松本克彦 ピグにおけるリアルタイムランキングの導入matsumoto_katsuhiko
 
実録 WEBエンジニアが Titanium Mobileアプリを開発するまで
実録 WEBエンジニアが Titanium Mobileアプリを開発するまで実録 WEBエンジニアが Titanium Mobileアプリを開発するまで
実録 WEBエンジニアが Titanium Mobileアプリを開発するまでYusaku Watanabe
 
iOS App performance tuning with Instruments
iOS App performance tuning with InstrumentsiOS App performance tuning with Instruments
iOS App performance tuning with Instrumentsgc-hiramatsu
 
iPhoneで動くFlash Playerを実装した苦労話LT資料
iPhoneで動くFlash Playerを実装した苦労話LT資料iPhoneで動くFlash Playerを実装した苦労話LT資料
iPhoneで動くFlash Playerを実装した苦労話LT資料Kohei Morino
 
海外向けサービスの苦労話
海外向けサービスの苦労話海外向けサービスの苦労話
海外向けサービスの苦労話Masakazu Matsushita
 
サーバの構築作業や運用管理を自動化する「Chef」 (CADC研究レポート発表LT)
サーバの構築作業や運用管理を自動化する「Chef」 (CADC研究レポート発表LT)サーバの構築作業や運用管理を自動化する「Chef」 (CADC研究レポート発表LT)
サーバの構築作業や運用管理を自動化する「Chef」 (CADC研究レポート発表LT)Yuuki Namikawa
 
kontagent紹介資料
kontagent紹介資料kontagent紹介資料
kontagent紹介資料Eiji Hachiya
 
From MongoDB v1.8.2 To v2.0.2
From MongoDB v1.8.2 To v2.0.2From MongoDB v1.8.2 To v2.0.2
From MongoDB v1.8.2 To v2.0.2Naoki Sega
 
研究開発レポート抜粋
研究開発レポート抜粋研究開発レポート抜粋
研究開発レポート抜粋Satoshi Udagawa
 
松本克彦 Flash stage3dに対応した3d物理演算ライブラリの検証
松本克彦 Flash stage3dに対応した3d物理演算ライブラリの検証松本克彦 Flash stage3dに対応した3d物理演算ライブラリの検証
松本克彦 Flash stage3dに対応した3d物理演算ライブラリの検証matsumoto_katsuhiko
 
SWFバージョン4においての テキスト形式による コンパイル結果の違い及び JavaScriptでの その描画方法に関する考察
SWFバージョン4においての テキスト形式による コンパイル結果の違い及び JavaScriptでの その描画方法に関する考察SWFバージョン4においての テキスト形式による コンパイル結果の違い及び JavaScriptでの その描画方法に関する考察
SWFバージョン4においての テキスト形式による コンパイル結果の違い及び JavaScriptでの その描画方法に関する考察Kazuhiro Kosaka
 
佐野裕章 Virident 社製半導体ストレージ flash max の検証
佐野裕章 Virident 社製半導体ストレージ flash max の検証佐野裕章 Virident 社製半導体ストレージ flash max の検証
佐野裕章 Virident 社製半導体ストレージ flash max の検証Hiroaki Sano
 
アメブロFaceの顔認識システム
アメブロFaceの顔認識システムアメブロFaceの顔認識システム
アメブロFaceの顔認識システムTakahiko Teramoto
 
アメーバピグとJenkinsと私
アメーバピグとJenkinsと私アメーバピグとJenkinsと私
アメーバピグとJenkinsと私Takashi Maruyama
 

Viewers also liked (18)

Matrix Factorizationを使った評価予測
Matrix Factorizationを使った評価予測Matrix Factorizationを使った評価予測
Matrix Factorizationを使った評価予測
 
Ca勉強会・ldについて
Ca勉強会・ldについてCa勉強会・ldについて
Ca勉強会・ldについて
 
OpenCVによる顔認識システムの開発
OpenCVによる顔認識システムの開発OpenCVによる顔認識システムの開発
OpenCVによる顔認識システムの開発
 
松本克彦 ピグにおけるリアルタイムランキングの導入
松本克彦 ピグにおけるリアルタイムランキングの導入松本克彦 ピグにおけるリアルタイムランキングの導入
松本克彦 ピグにおけるリアルタイムランキングの導入
 
実録 WEBエンジニアが Titanium Mobileアプリを開発するまで
実録 WEBエンジニアが Titanium Mobileアプリを開発するまで実録 WEBエンジニアが Titanium Mobileアプリを開発するまで
実録 WEBエンジニアが Titanium Mobileアプリを開発するまで
 
iOS App performance tuning with Instruments
iOS App performance tuning with InstrumentsiOS App performance tuning with Instruments
iOS App performance tuning with Instruments
 
iPhoneで動くFlash Playerを実装した苦労話LT資料
iPhoneで動くFlash Playerを実装した苦労話LT資料iPhoneで動くFlash Playerを実装した苦労話LT資料
iPhoneで動くFlash Playerを実装した苦労話LT資料
 
海外向けサービスの苦労話
海外向けサービスの苦労話海外向けサービスの苦労話
海外向けサービスの苦労話
 
サーバの構築作業や運用管理を自動化する「Chef」 (CADC研究レポート発表LT)
サーバの構築作業や運用管理を自動化する「Chef」 (CADC研究レポート発表LT)サーバの構築作業や運用管理を自動化する「Chef」 (CADC研究レポート発表LT)
サーバの構築作業や運用管理を自動化する「Chef」 (CADC研究レポート発表LT)
 
Inside png
Inside pngInside png
Inside png
 
kontagent紹介資料
kontagent紹介資料kontagent紹介資料
kontagent紹介資料
 
From MongoDB v1.8.2 To v2.0.2
From MongoDB v1.8.2 To v2.0.2From MongoDB v1.8.2 To v2.0.2
From MongoDB v1.8.2 To v2.0.2
 
研究開発レポート抜粋
研究開発レポート抜粋研究開発レポート抜粋
研究開発レポート抜粋
 
松本克彦 Flash stage3dに対応した3d物理演算ライブラリの検証
松本克彦 Flash stage3dに対応した3d物理演算ライブラリの検証松本克彦 Flash stage3dに対応した3d物理演算ライブラリの検証
松本克彦 Flash stage3dに対応した3d物理演算ライブラリの検証
 
SWFバージョン4においての テキスト形式による コンパイル結果の違い及び JavaScriptでの その描画方法に関する考察
SWFバージョン4においての テキスト形式による コンパイル結果の違い及び JavaScriptでの その描画方法に関する考察SWFバージョン4においての テキスト形式による コンパイル結果の違い及び JavaScriptでの その描画方法に関する考察
SWFバージョン4においての テキスト形式による コンパイル結果の違い及び JavaScriptでの その描画方法に関する考察
 
佐野裕章 Virident 社製半導体ストレージ flash max の検証
佐野裕章 Virident 社製半導体ストレージ flash max の検証佐野裕章 Virident 社製半導体ストレージ flash max の検証
佐野裕章 Virident 社製半導体ストレージ flash max の検証
 
アメブロFaceの顔認識システム
アメブロFaceの顔認識システムアメブロFaceの顔認識システム
アメブロFaceの顔認識システム
 
アメーバピグとJenkinsと私
アメーバピグとJenkinsと私アメーバピグとJenkinsと私
アメーバピグとJenkinsと私
 

Similar to アメーバピグのサーバとクライアントはどうやって通信しているのか

Community Open Day 沖縄
Community Open Day 沖縄Community Open Day 沖縄
Community Open Day 沖縄Yutaka Tsumori
 
ソシャゲにおけるサーバとクライアントの決めごと
ソシャゲにおけるサーバとクライアントの決めごとソシャゲにおけるサーバとクライアントの決めごと
ソシャゲにおけるサーバとクライアントの決めごとpeto_tn
 
ドメイン駆動設計 ( DDD ) をやってみよう
ドメイン駆動設計 ( DDD ) をやってみようドメイン駆動設計 ( DDD ) をやってみよう
ドメイン駆動設計 ( DDD ) をやってみよう増田 亨
 
剣と魔法のログレス いにしえの女神 〜スマホ時代の MMORPG を支える技術
剣と魔法のログレス いにしえの女神 〜スマホ時代の MMORPG を支える技術剣と魔法のログレス いにしえの女神 〜スマホ時代の MMORPG を支える技術
剣と魔法のログレス いにしえの女神 〜スマホ時代の MMORPG を支える技術Satoshi Yamafuji
 
Oedo Ruby Conference 04: Ruby会議でSQLの話をするのは間違っているだろうか
Oedo Ruby Conference 04: Ruby会議でSQLの話をするのは間違っているだろうかOedo Ruby Conference 04: Ruby会議でSQLの話をするのは間違っているだろうか
Oedo Ruby Conference 04: Ruby会議でSQLの話をするのは間違っているだろうかMinero Aoki
 
WindowsAzureの長所を活かすクラウド アプリ開発(PDF版)
WindowsAzureの長所を活かすクラウド アプリ開発(PDF版)WindowsAzureの長所を活かすクラウド アプリ開発(PDF版)
WindowsAzureの長所を活かすクラウド アプリ開発(PDF版)Shinichiro Isago
 
Implements OpenTelemetry Collector in DotNet
Implements OpenTelemetry Collector in DotNetImplements OpenTelemetry Collector in DotNet
Implements OpenTelemetry Collector in DotNetYoshifumi Kawai
 
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例Yoshifumi Kawai
 
C++0xの概要(デブサミ2010)
C++0xの概要(デブサミ2010)C++0xの概要(デブサミ2010)
C++0xの概要(デブサミ2010)Akira Takahashi
 
DEV-011_TypeScript ~Any browser. Any host. Any OS. Open Source~
DEV-011_TypeScript ~Any browser. Any host. Any OS. Open Source~DEV-011_TypeScript ~Any browser. Any host. Any OS. Open Source~
DEV-011_TypeScript ~Any browser. Any host. Any OS. Open Source~decode2016
 
PHPからJavaへ乗り換えた。そんな昔話をしよう
PHPからJavaへ乗り換えた。そんな昔話をしようPHPからJavaへ乗り換えた。そんな昔話をしよう
PHPからJavaへ乗り換えた。そんな昔話をしよう優介 黒河
 
Wiresharkの解析プラグインを作る ssmjp 201409
Wiresharkの解析プラグインを作る ssmjp 201409Wiresharkの解析プラグインを作る ssmjp 201409
Wiresharkの解析プラグインを作る ssmjp 201409稔 小林
 
Apache Avro vs Protocol Buffers
Apache Avro vs Protocol BuffersApache Avro vs Protocol Buffers
Apache Avro vs Protocol BuffersSeiya Mizuno
 
Apache Camel Netty component
Apache Camel Netty componentApache Camel Netty component
Apache Camel Netty componentssogabe
 
TypeScript と Visual Studio Code
TypeScript と Visual Studio CodeTypeScript と Visual Studio Code
TypeScript と Visual Studio CodeAkira Inoue
 
LEGO MINDSTORMS EV3 API
LEGO MINDSTORMS EV3 APILEGO MINDSTORMS EV3 API
LEGO MINDSTORMS EV3 APIAkira Hatsune
 
Hello ".NET" World
Hello ".NET" WorldHello ".NET" World
Hello ".NET" World将 高野
 

Similar to アメーバピグのサーバとクライアントはどうやって通信しているのか (20)

P2Pって何?
P2Pって何?P2Pって何?
P2Pって何?
 
Community Open Day 沖縄
Community Open Day 沖縄Community Open Day 沖縄
Community Open Day 沖縄
 
ソシャゲにおけるサーバとクライアントの決めごと
ソシャゲにおけるサーバとクライアントの決めごとソシャゲにおけるサーバとクライアントの決めごと
ソシャゲにおけるサーバとクライアントの決めごと
 
ドメイン駆動設計 ( DDD ) をやってみよう
ドメイン駆動設計 ( DDD ) をやってみようドメイン駆動設計 ( DDD ) をやってみよう
ドメイン駆動設計 ( DDD ) をやってみよう
 
剣と魔法のログレス いにしえの女神 〜スマホ時代の MMORPG を支える技術
剣と魔法のログレス いにしえの女神 〜スマホ時代の MMORPG を支える技術剣と魔法のログレス いにしえの女神 〜スマホ時代の MMORPG を支える技術
剣と魔法のログレス いにしえの女神 〜スマホ時代の MMORPG を支える技術
 
Oedo Ruby Conference 04: Ruby会議でSQLの話をするのは間違っているだろうか
Oedo Ruby Conference 04: Ruby会議でSQLの話をするのは間違っているだろうかOedo Ruby Conference 04: Ruby会議でSQLの話をするのは間違っているだろうか
Oedo Ruby Conference 04: Ruby会議でSQLの話をするのは間違っているだろうか
 
WindowsAzureの長所を活かすクラウド アプリ開発(PDF版)
WindowsAzureの長所を活かすクラウド アプリ開発(PDF版)WindowsAzureの長所を活かすクラウド アプリ開発(PDF版)
WindowsAzureの長所を活かすクラウド アプリ開発(PDF版)
 
Enshu5
Enshu5Enshu5
Enshu5
 
Implements OpenTelemetry Collector in DotNet
Implements OpenTelemetry Collector in DotNetImplements OpenTelemetry Collector in DotNet
Implements OpenTelemetry Collector in DotNet
 
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
Metaprogramming Universe in C# - 実例に見るILからRoslynまでの活用例
 
C++0xの概要(デブサミ2010)
C++0xの概要(デブサミ2010)C++0xの概要(デブサミ2010)
C++0xの概要(デブサミ2010)
 
DEV-011_TypeScript ~Any browser. Any host. Any OS. Open Source~
DEV-011_TypeScript ~Any browser. Any host. Any OS. Open Source~DEV-011_TypeScript ~Any browser. Any host. Any OS. Open Source~
DEV-011_TypeScript ~Any browser. Any host. Any OS. Open Source~
 
Android bluetooth
Android bluetoothAndroid bluetooth
Android bluetooth
 
PHPからJavaへ乗り換えた。そんな昔話をしよう
PHPからJavaへ乗り換えた。そんな昔話をしようPHPからJavaへ乗り換えた。そんな昔話をしよう
PHPからJavaへ乗り換えた。そんな昔話をしよう
 
Wiresharkの解析プラグインを作る ssmjp 201409
Wiresharkの解析プラグインを作る ssmjp 201409Wiresharkの解析プラグインを作る ssmjp 201409
Wiresharkの解析プラグインを作る ssmjp 201409
 
Apache Avro vs Protocol Buffers
Apache Avro vs Protocol BuffersApache Avro vs Protocol Buffers
Apache Avro vs Protocol Buffers
 
Apache Camel Netty component
Apache Camel Netty componentApache Camel Netty component
Apache Camel Netty component
 
TypeScript と Visual Studio Code
TypeScript と Visual Studio CodeTypeScript と Visual Studio Code
TypeScript と Visual Studio Code
 
LEGO MINDSTORMS EV3 API
LEGO MINDSTORMS EV3 APILEGO MINDSTORMS EV3 API
LEGO MINDSTORMS EV3 API
 
Hello ".NET" World
Hello ".NET" WorldHello ".NET" World
Hello ".NET" World
 

アメーバピグのサーバとクライアントはどうやって通信しているのか

  • 2. アジェンダ ・自己紹介 ・アメーバピグとは ・アメーバピグのシステムアーキテクチャ ・クライアントとサーバ間の通信方法 ・ CommandID での通信 ・ MethodName での通信 ・まとめ
  • 4. 田中 広海 ( たなひろ ) 株式会社サイバーエージェント アメーバ事業本部所属 2010 年 2 月中途入社 Twitter : @tn_hiro 職歴:ゲーム会社、携帯コンテンツ開発 趣味:ガッツリいろいろと・・・
  • 8. HadoopCluster FileStorage Database Game Server Chat Server Info Server Web Server
  • 9. HadoopCluster FileStorage Database Game Server Chat Server Info Server Web Server Hadoop ユーザ行動 Log
  • 10. HadoopCluster FileStorage Database Game Server Chat Server Info Server Web Server Isilon 商用分散 storage
  • 11. HadoopCluster FileStorage Database Game Server Chat Server Info Server Web Server MySql + FusionIO + Memcached
  • 12. HadoopCluster FileStorage Database Game Server Chat Server Info Server Web Server Flash,Image を配信
  • 13. HadoopCluster FileStorage Database Game Server Chat Server Info Server Web Server ユーザ情報の通信
  • 14. HadoopCluster FileStorage Database Game Server Chat Server Info Server Web Server チャットデータ エリア情報の通信
  • 15. HadoopCluster FileStorage Database Game Server Chat Server Info Server Web Server ChatServer + ゲーム情報の通信
  • 17. サーバ Java Application java.net.Socket を使用 クライアント Flash(ActionScript3.0) flash.net.Socket を使用
  • 20. Flash (クライアント) 側 から Java( サーバ ) への送信 public static const TALK:int = 0x0000; public function writeData(bytes:ByteArray):void   var bytes:ByteArray = new ByteArray()   bytes.writeByte(TALK);   bytes.writeUTF(message);   bytes.writeUnsignedInt(color); }
  • 21. Java( サーバ ) で受信 public static final short TALK = 0x0000; public class TalkData implements CommandData{   public void readData(ByteBuilder in) {    byte commandId = in.getByte();    String message = in.getUTF();    int color = in.getInt();      talk(user, message, color);   } }
  • 22. 同一エリア内のユーザに配信 public void talk(ChatUser user, String message, int color)    throws ServiceException {   // 今いるエリアを取得   ChatArea chatArea = user.getChatArea();   // 話した内容を Data(Command) 化   TalkResultData talkResult = new TalkResultData(user.getAmebaId(),                        user.getNickname(),                        message,                        color);   // broadcast   for (ChatUser user : chatArea.getUsers()) {    CommandConnection conn = user.getConnection();    conn.sendCommand(talkResult);   } }
  • 23. public static final short TALK_RESULT = 0x0001; public class TalkResultData implements CommandData{   public TalkResultData(String amebaId, String nickname,            String message, int color) {    this.commandId = CommandId.TALK_RESULT;    this.amebaId = Binaries.toBytes(amebaId);    this.nickname = Binaries.toBytes(nickname);    this.messageByte = Binaries.toBytes(message);    this.color = color;   }   // Java( サーバ ) 側 から Flash (クライアント) への送信   public void writeData(ByteBuilder out) {    out.put Byte (commandId);    out.putShort((short)messageByte.length);    out.put(messageByte);    out.putInt(color);    out.putShort((short)amebaId.length);    out.put(amebaId);    out.putShort((short)nickname.length);    out.put(nickname);   } }
  • 24. Flash (クライアント) の 受信 public static const TALK_RESULT:int = 0x0001; public function readData(bytes:ByteArray):void {   commandId = bytes.readUnsignedByte();   message = bytes.readUTF();   color = bytes.readUnsignedInt();   amebaId = bytes.readUTF();   nickname = bytes.readUTF(); } public function talk(msg:String, color:uint):void   _chat.addBubble(new ChatBubble(msg, color)); }
  • 25. Flash (クライアント) の 受信 public static const TALK_RESULT:int = 0x0001; public function readData(bytes:ByteArray):void {   commandId = bytes.readUnsignedByte();   message = bytes.readUTF();   color = bytes.readUnsignedInt();   amebaId = bytes.readUTF();   nickname = bytes.readUTF(); } public function talk(msg:String, color:uint):void   _chat.addBubble(new ChatBubble(msg, color)); }
  • 27. TALK 0x0000 TALK_RESULT 0x0001 MOVE 0x0002 MOVE_RESULT 0x0003
  • 28. TALK 0x0000 MOVE 0x0002 switch (commandId) {   case TALK:    talk();    break;   case MOVE:    move();    break; }
  • 30. ・ ID を割り振るのはメンドクサイ   Java 側と Flash 側で同じ番号を振らないといけない ・ 直接番号を振っているので、   0x000F と 0x0010 の間に   別のコマンドを足したいと思っても足せない ・ ID と実行メソッドの関連付けのために   switch 文の修正が必要
  • 31. ・ ID を割り振るのはメンドクサイ   Java 側と Flash 側で同じ番号を振らないといけない ・ 直接番号を振っているので、   0x000F と 0x0010 の間に   別のコマンドを足したいと思っても足せない ・ ID と実行メソッドの関連付けのために   switch 文の修正が必要 ↓ MethodName での Command 呼び出しが 実装されました!
  • 33. Flash 送信 部 public function writeData(bytes:ByteArray):void   var bytes:ByteArray = new ByteArray()   bytes.putUTFNullEmpty(&quot;talk&quot;);   bytes.writeByte(CommandId.TALK);   bytes.writeUTF(message);   bytes.writeUnsignedInt(color); } Java 側 分岐 private Map<String, Method> serviceMethods; Method method = serviceMethods.get( methodName ); method.invoke();
  • 35. ・ Flash 側で設定した MethodName によって、   サーバ側が分岐する ・ Java 側のソースだけだと、   どの Method がいつ呼ばれるかわからない。 ・ CommandId 仕様であれば、   (CommandId の宣 言部分が一 ヶ所に固まっているので )   処理部を検索する時にも grep 出来て楽だった。
  • 36. まとめ ・ commandId での方法も、 MethodName での方法も   一長一短   新規で機能を実装するなら、 MethodName の方が   コードを書く量が少なくて楽 ・ 速度重視の開発という意味では、 MethodName おすすめ ・ 後でまったく知らない人がソース読むときには大変かも