Java プロコンゲーム 〜Socket通信を設計する〜

今回は、プロコンゲーム(プログラミングコンテスト向けゲーム)の作成を続きでSocket通信の設計を行います。

フローチャート

UMLの中にある「フローチャート」を作成します。
今回作成するSocket通信の役割は、大まかに以下のようなものです。

  1. 通信してプロコンゲームの受付をする。
  2. ゲーム開始後にプレーヤーの挙動を受信、画面上の操作を行い、レスポンスをクライアントアプリに返す。

上のようなイメージです。なので前回作成した画面部分から今度は処理部分(画面表示なし)を作成します。

Socket通信とは

「通信」と名前がついているので、何かしらの通信を行うであろうと想像はつくと思います、しかし、HTTP通信とか、TCPとか、XML、JSONとか。。。
どれよ?と思う人も多いでしょう(自分は頭から煙を吹いていました(笑))
通信を行うときはどの通信処理でも最終的に「TCP/IP」で通信を行います。特殊なものを覗きますが。。。だいたいJavaで実装するとかJSなど最近の言語であればほぼTCP_IPの通信になります。

そして、TCP/IPはデータを送信するためのポートから対象になるURLやIPアドレスに向けて送信されます。

URLは最終的にDNSで変換されてIPアドレスになるので、結局は 指定されたIPアドレスに送信されるというわけです。

細かい話をしましたが、早い話がポートから対象のアドレスへデータを送信します。
この時に使用する「ポート」これを「ソケット」と呼びます。つまり「Socket通信」を行うというわけです。

Scoketクラスとは

いろんな言語で「ソケット通信」用のクラス、オブジェクトがAPIとして用意されています。当然Javaにもあり、それは「低レベルAPI」と呼ばれる部類に入ります。
つまりは、やりたい放題なAPIというわけです。
Javaで使用するSocketクラスはファイル入出力の処理に似ています。
Fileの作成、読み取り、書き込みこれらの処理で使用する「ストリーム」を使用して通信を行うためです。
なのでFIleクラスの扱い方を理解しているとあとあと楽ができます。

Socketの実装

まず、Socketには2種類あります。以下に示すようにサーバーとクライアントがあります。

  1. Socket
  2. ServerSocket

Socketクラスは、ソケット通信を行うためのクラスで、クライアントプログラムになります。つまり、リクエストを送信する側のプログラムです。

以下のような処理を行います。

  1. 送信するポートを指定
  2. 対象のサーバーに接続
  3. データの送信
  4. レスポンスの取得

ServerSocketの実装

それに対してServerSocketはサーバーサイドプログラムで、レスポンスを返す側のプログラムです。
なので使用するときは、単純に、ServerSocketクラスのインスタンスを作成し、通信を待ち受けます。

まとめると以下のような処理です。

  1. インスタンスの生成、待ち受けるポートの指定
  2. リクエスト受信の待機

そして、待ち受けはリクエストを受けたら。。。なにがしかの処理を行うので、ゲームループと同じような実装を行い、サーバーを終了させるには別の手段が必要になります。
例えば、『リクエストの「bye」という文字を受信したらプログラムを閉じる』というような処理です。

プログラムの実装の前に

前回、プロコンアプリを作成した時には、設計を行わないで実装したので、汚いソースができました。これらのコードは Githubにアップしてあります。

以前作成したゲームループ処理の記事もあるので参考にどうぞ。

ゲームループの実装イメージ

なので、設計から入ります。

Socket通信の設計

UMLに追記する形で、設計を行います。
大まかに下のような形で設計しました。

詳細は、以下の通りです。

とりあえずは、ServerSocketから実装し行きますが、受信ポートと、受付処理の実装を行うのでそこの部分をメソッド、クラスに分担してやるように設計します。

実装イメージを考える

ServerSocketの実装は上記の通りに以下のようになります。

  1. インスタンスの生成、待ち受けるポートの指定
  2. リクエスト受信の待機

なので、受付した時のイメージファイルの取得とかデータからプレーヤステータスの作成とか細かい部分に関しては、ServerSocketを実装するクラスで行いたくありません。

具体的には、下のように
JSONを使用してデータの通信を行います。
これは、JavaだけでなくPythonや C#などの多言語での実装を可能にするためです。

なので、PlayerDataクラスをJSONにコンバートして送受信します。送受信するJSONのデータ形式に関しては、ドキュメントにて実装者にわかるようにします。

処理フロー

Server

  1. サーバー起動、受付開始
  2. クライアント受付、プレーヤー登録
  3. スタートボタン押下
  4. バトルMapの表示
  5. キャラクター(Playerなど)配置
  6. クライアントへのレスポンス送信
  7. リクエスト受信
  8. 各キャラクターの操作と描画
  9. 操作後の情報をクライアントへレスポンス送信
  10. 7〜9を繰り返す

Client

  1. プレーヤー定義情報の読み込み
  2. サーバーへの接続
  3. プレーヤー定義情報の送信
  4. サーバーからのレスポンス受信
  5. 何かしらの処理(今後設計する)
  6. サーバーへリクエスト送信
  7. 4〜6を繰り返す
  8. 終了コマンドを受け取った時にアプリ終了

上のような感じで処理を行おうと考えています。

下の方に、補足情報を記載しておきます。
今までの記事(プロコンサーバー作成)にも記載している内容です。参考にどうぞ。

JavaFXの基本的なところ

細かい書き方などは下のリンク先に記載しています。

  1. UML 世界を作る 〜RPGでの世界を作る場合〜
  2. UMLの書き方(読み方)〜概要とクラス図〜
  3. UMLツール Star UML〜ユースケース図を書いて見た〜
  4. UMLツール 〜Star UMLを使う〜

javaFXはフレームワークです。なのでとりあえず下のように作成しました。参考にどうぞ。
JavaFXのパッケージにあるjavafx.application.Applicationを継承して作成します。
ここで、上のクラスを継承して実装することにより、画面表示を行うための細かい処理(Xサーバーへのアクセス及び、描画処理)を自分で作成しなくてよくなります。

つまり、作成するアプリに集中できるわけです。
その代わり、このフレームワークの使用方法を理解する必要があります。「JavaFXの〜」にあるリンクからOracleのドキュメントページに遷移できます。

自分の作成した記事は以下になります。
初心者でもわかる。。。というより作って動かして。。。とやってみるのが一番なのでその手順と実装サンプル、動かしてみたときのイメージを記載しています。

  1. JavaFX チュートリアル〜今度こそ、初めてでも大丈夫:Label〜
  2. JavaFX チュートリアル〜今度こそ、初めてでも大丈夫2:Label〜
  3. JavaFX チュートリアル〜今度こそ、初めてでも大丈夫3:Button〜

プロジェクトの作成方法

  1. プロジェクトエクスプローラーを右クリックします。
  2. JavaFXプロジェクトを作成します。
  3. プロジェクト名をつけます。使用するJDKは1.8です。JShellとか使用する予定がないので。。。

作成したプロジェクトは下のような感じです。

以前追加した、シーンビルダーというプラグインが入っているので、使用します。下は操作したときの動画です。今回作成するものではありませんので。。。

そして、作成したものは、下のような見た目です。

作成したときの動画は以下になります。途中で落ちましたが(笑)とりあえずは、使用するPCのスペックでメモリ不足(だと思う)により落ちる可能性があるので、File -> Save Asなどで時々保存すると良いと思います。

SceneBuilder

SceneBuilderは下のように作成しました。
SceneBuilderのセットアップはこちらを参照ください。

前回SceneBuilderを使用して作成した、FXMLは下のようEclipseのリソースフォルダへコピーしてプログラムから参照できるようにします。

まとめ

今回は、Socketを使用して実装するのにどう処理を行うかを考えました(設計しました)。
実装してみれば、Socket通信に関して理解ができると思います。
そして、低レベルAPIなので現在使用されるほとんどのデータ通信の土台になります。

つまり、ここがわかれば、他も理解できるということです。

今回はここら辺で。。。
でわでわ。。。

関連ページ

Java Basic

  1. Java Basic Level 1 Hello Java
  2. Java Basic Level2 Arithmetic Calculate
  3. Java Basic Level3 About String class
  4. Java Basic Level 4Boolean
  5. Java Basic Level 5If Statement
  6. Java Basic Summary from Level1 to 5
  7. Java Basic Level 6 Traning of If statement
  8. Java Basic Level8 How to use for statement
  9. Java Basic Level 8.5 Array
  10. Java Basic Level 9Training of for statement
  11. Java Basic Level 10 While statement 
  12. Java Basic Swing〜オブジェクト指向〜
  13. Java Basic Swing Level 2〜オブジェクト指向2
  14. サンプル実装〜コンソールゲーム〜
  15. Java Basic インターフェース・抽象クラスの作り方
  16. Java Basic クラスとは〜Step2_1
  17. Java Basic JUnit 〜テストスイートの作り方〜