今回は、プロコンゲーム(プログラミングコンテスト向けゲーム)の作成を続きでSocket通信の設計を行います。
フローチャート
「フローチャート」を作成し処理の流れを可視化します。
今回作成するSocket通信の役割は、大まかに以下のようなものです。
- 通信してプロコンゲームの受付をする。
- ゲーム開始後にプレーヤーの挙動を受信、画面上の操作を行い、レスポンスをクライアントアプリに返す。
上のようなイメージです。なので前回作成した画面部分から今度は処理部分(画面表示なし)を作成します。
最終的には画面を起動してSoket通信を起動して、画面の表示と通信を同時に行う予定です。(マルチスレッド処理)
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種類あります。以下に示すようにサーバーとクライアントがあります。*JavaDocへのリンク
- Socket
- ServerSocket
Socketクラスは、ソケット通信を送信ためのクラスで、クライアントプログラムになります。つまり、リクエストを送信し、レスポンスを受け取る側のプログラムです。
以下のような処理を行います。
- 送信するポートを指定
- 対象のサーバーに接続
- リクエストの送信
- レスポンスの取得
ServerSocketの実装
それに対してServerSocketはサーバーサイドプログラムで、レスポンスを返す側のプログラムです。
なので使用するときは、単純に、ServerSocketクラスのインスタンスを作成し、通信を待ち受けます。
まとめると以下のような処理です。
- インスタンスの生成、待ち受けるポートの指定
- リクエスト受信の待機
そして、待ち受けはリクエストを受けたら。。。なにがしかの処理を行うので、ゲームループと同じような実装を行い、サーバーを終了させるには別の手段が必要になります。
例えば、『リクエストの「bye」という文字を受信したらプログラムを終了する』というような処理です。
プログラムの実装の前に
前回、プロコンアプリ(U16-プログラミングコンテスト)を作成した時には、設計を行わないで実装したので、汚いソースができました。これらのコードは Githubにアップしてあります。
以前作成したゲームループ処理の記事もあるので参考にどうぞ。
ゲームループの実装イメージ
なので、設計から入り、どの様に実装するのか?を明確にして実装します。
更に、各処理の仕様を作ってから開発するので、テスト駆動開発でやります。*テスト駆動開発をやってみた時の記事へのリンクです。
Socket通信の設計
UMLに追記する形で、設計を行います。
大まかに下のような形で設計しました。
詳細は、以下の通りです。
とりあえずは、ServerSocketから実装し行きますが、受信ポートと、受付処理の実装を行うのでそこの部分をメソッド、クラスに分担してやるように設計します。
実装イメージを考える
ServerSocketの実装は上記の通りに以下のようになります。
- インスタンスの生成、待ち受けるポートの指定
- リクエスト受信の待機
なので、受付した時のイメージファイルの取得とかデータからプレーヤステータスの作成とか細かい部分に関しては、ServerSocketを実装するクラスで行いたくありません。
具体的には、下のように
JSONを使用してデータの通信を行います。
これは、JavaだけでなくPythonや C#などの多言語での実装を可能にするためです。
なので、PlayerDataクラスをJSONにコンバートして送受信します。送受信するJSONのデータ形式に関しては、ドキュメントにて実装者にわかるようにします。
しかし、設計を進めていく中で、クラスをクライアントからサーバーへ送信したいと思い、その様な設計にしたので現状はしJavaでのみ通信可能な設計になっています。
処理フロー
Server
- サーバー起動、受付開始
- クライアント受付、プレーヤー登録
- スタートボタン押下
- バトルMapの表示
- キャラクター(Playerなど)配置
- クライアントへのレスポンス送信
- リクエスト受信
- 各キャラクターの操作と描画
- 操作後の情報をクライアントへレスポンス送信
- 7〜9を繰り返す
Client
- プレーヤー定義情報の読み込み
- サーバーへの接続
- プレーヤー定義情報の送信
- サーバーからのレスポンス受信
- 何かしらの処理(今後設計する)
- サーバーへリクエスト送信
- 4〜6を繰り返す
- 終了コマンドを受け取った時にアプリ終了
上のような感じで処理を行おうと考えています。
下の方に、補足情報を記載しておきます。
今までの記事(プロコンサーバー作成)にも記載している内容です。参考にどうぞ。
UML の基本的なところ
細かい書き方などは下のリンク先に記載しています。
- UML 世界を作る 〜RPGでの世界を作る場合〜
- UMLの書き方(読み方)〜概要とクラス図〜
- UMLツール Star UML〜ユースケース図を書いて見た〜
- UMLツール 〜Star UMLを使う〜
UML で大まかな設計をして、使用するクラスの一覧を作ってしまいます。
画面作成JavaFX
javaFXはフレームワークです。なのでとりあえず下のように作成しました。参考にどうぞ。
JavaFXのパッケージにあるjavafx.application.Application
を継承して作成します。
ここで、上のクラスを継承して実装することにより、画面表示を行うための細かい処理(Xサーバーへのアクセス及び、描画処理)を自分で作成しなくてよくなります。
つまり、作成するアプリに集中できるわけです。
その代わり、このフレームワークの使用方法を理解する必要があります。「JavaFXの〜」にあるリンクからOracleのドキュメントページに遷移できます。
自分の作成した記事は以下になります。
初心者でもわかる。。。というより作って動かして。。。とやってみるのが一番なのでその手順と実装サンプル、動かしてみたときのイメージを記載しています。
- JavaFX チュートリアル〜今度こそ、初めてでも大丈夫:Label〜
- JavaFX チュートリアル〜今度こそ、初めてでも大丈夫2:Label〜
- JavaFX チュートリアル〜今度こそ、初めてでも大丈夫3:Button〜
プロジェクトの作成方法
- プロジェクトエクスプローラーを右クリックします。
- JavaFXプロジェクトを作成します。
- プロジェクト名をつけます。使用するJDKは1.8です。JShellとか使用する予定がないので。。。
作成したプロジェクトは下のような感じです。
以前追加した、シーンビルダーというプラグインが入っているので、使用します。下は操作したときの動画です。今回作成するものではありませんので。。。
そして、作成したものは、下のような見た目です。
作成したときの動画は以下になります。途中で落ちましたが(笑)とりあえずは、使用するPCのスペックでメモリ不足(だと思う)により落ちる可能性があるので、File -> Save Asなどで時々保存すると良いと思います。
SceneBuilder
Java FXでの画面作成ツールです。ボタン押下時の処理などは別途実装が必要になります。
SceneBuilderは下のように作成しました。
SceneBuilderのセットアップはこちらを参照ください。
前回SceneBuilderを使用して作成した、FXMLは下のようEclipseのリソースフォルダへコピーしてプログラムから参照できるようにします。
まとめ
今回は、Socketを使用して実装するのにどう処理を行うかを考えました(設計しました)。
実装してみれば、Socket通信に関して理解ができると思います。
そして、低レベルAPIなので現在使用されるほとんどのデータ通信の土台になります。
つまり、ここがわかれば、他も理解できるということです。
今回はここら辺で。。。
でわでわ。。。
関連ページ
Java Basic
- Java Basic Level 1 〜Hello Java〜
- Java Basic Level2 〜Arithmetic Calculate〜
- Java Basic Level3 〜About String class〜
- Java Basic Level 4〜Boolean〜
- Java Basic Level 5〜If Statement〜
- Java Basic Summary from Level1 to 5
- Java Basic Level 6 〜Traning of If statement〜
- Java Basic Level8 〜How to use for statement〜
- Java Basic Level 8.5 〜Array〜
- Java Basic Level 9〜Training of for statement〜
- Java Basic Level 10 〜While statement 〜
- Java Basic Swing〜オブジェクト指向〜
- Java Basic Swing Level 2〜オブジェクト指向2〜
- サンプル実装〜コンソールゲーム〜
- Java Basic インターフェース・抽象クラスの作り方
- Java Basic クラスとは〜Step2_1〜
- Java Basic JUnit 〜テストスイートの作り方〜