前回まで、90xiで動作するネットワーク対応のカードゲームの作り方を紹介してきた。最終回はこのアプリをもっと展開させていくための手法と、90xiアプリのこれからについて解説しよう。
赤外線通信を使えば通信費をかけずにデータのやり取りができる。これを用いれば、カードゲームへの応用として、ユーザ間でのカード交換を実現できる。
赤外線通信のモデルは、サーバ/クライアントモデルとなっている。サーバが待機状態になっている時にクライアントがデータを送信したり、また、データを要求して受信したりすることができる。サーバとクライアントはセットで使用しなければならないので、両方のサンプルを紹介する。HTTP通信と似ているため、理解しやすいだろう。
以下がクライアントのプログラムである。
// 受信/送信するカード番号
int card_recv, card_send;
// ClientObexConnectionオブジェクトを用意
ClientObexConnection coc;
try {
// HTTPの接続と同様にConnector.open()を用いる
// URLの代わりに、クライアントの場合はロケーションに
// "obex:/irclient"を指定する。
coc = (ClientObexConnection) Connector.open("obex:/irclient",
Connector.READ_WRITE, true);
// 接続を行う
coc.connect();
// GETオペレーションの実行
coc.setOperation(ObexConnection.GET);
coc.setName("card_recv"); // GET 対象オブジェクトの名前を設定
coc.sendRequest(); // オペレーションを送信
// OBEX サーバから返却されたレスポンスコードをチェックし、
// 正常であれば受信したオブジェクト本体を読み込む
if (coc.getResponseCode() == ObexConnection.SUCCESS) {
InputStream is = coc.openInputStream();
// GETオペレーションで要求したデータの読み込み処理
int isbuf;
byte[] single = new byte[1];
ByteArrayOutputStream baos =
new ByteArrayOutputStream();
for(;;) {
if((isbuf = is.read(single)) < 0) {
break;
}
baos.write(single);
}
is.close();
card_recv = Integer.parseInt
(baos.toString());
in.close();
} else {
throw new IOException();
}
// PUTオペレーションの実行
coc.setOperation(ObexConnection.PUT); // オペレーションにPUTを設定
coc.setName("card_send"); // PUT 対象オブジェクトの名前を設定
coc.setType("text/plain"); // PUT 対象オブジェクトのタイプを設定
coc.setTime(System.currentTimeMillis()); // PUT 対象オブジェクトの
// タイムスタンプを設定
OutputStream os = coc.openOutputStream();
// PUTオペレーションで送信するデータの書き込み処理
os.write((byte)card_send);
os.close();
coc.sendRequest(); // オペレーションを送信
// レスポンスコードが正常であればClientObexConnection を閉じて処理終了
if (coc.getResponseCode() != ObexConnection.SUCCESS) {
throw new IOException();
}
coc.close();
} catch (IOException ioe) {
//例外処理
//API がスローするIOException、ConnectionException、
//アプリケーションプログラムがスローするIOException の処理を行う
}
| |
以下がサーバのプログラムである。
int server_recv, server_send;
// ServerObexConnectionオブジェクトを用意
ServerObexConnection soc;
try {
// ServerObexConnection インスタンスを取得する
// サーバの場合のロケーションは、"obex:/irserver"
soc = (ServerObexConnection) Connector.open(
"obex:/irserver", Connector.READ_WRITE, true);
// OBEX クライアントからの通信リンク確立要求を待ち合わせる
soc.accept();
// OBEX クライアントからのオペレーション要求を処理する
while (true) {
// オペレーション要求を待つ
soc.receiveRequest();
// 到着したオペレーションの種別を取得する
int operation = soc.getOperation();
// GET オペレーション要求
if (operation == ObexConnection.GET) {
// 要求されたオブジェクトの名前を取得
String name = soc.getName();
// 指定された名前に対応するオブジェクトのヘッダ情報を設定
soc.setType("text/plain");
soc.setTime(System.currentTimeMillis());
// 指定された名前に対応するオブジェクトの書き込み処理
OutputStream os = soc.openOutputStream();
if (name.equals("card_recv")) {
os.write((byte)server_send);
}
os.close();
// 正常終了を示すステータスコードをOBEXクライアントに返す
soc.sendResponse(ObexConnection.SUCCESS);
} else if (operation == ObexConnection.PUT) {
// PUTオペレーション要求
// 送信されたオブジェクトの各種情報を取得
String name = soc.getName();
String type = soc.getType();
long time = soc.getTime();
// 送信されたオブジェクトの読み出し処理
InputStream is = soc.openInputStream();
if (name.equals("card_send")) {
int isbuf;
byte[] single = new byte[1];
ByteArrayOutputStream baos =
new ByteArrayOutputStream();
for(;;) {
if((isbuf = is.read(single)) < 0) {
break;
}
baos.write(single);
}
is.close();
server_recv = Integer.parseInt
(baos.toString());
}
is.close();
// 正常終了を示すステータスコードをOBEXクライアントに返す
soc.sendResponse(ObexConnection.SUCCESS);
} else if (operation ==
ObexConnection.DISCONNECT) { // 切断要求
break;
}
}
// 通信リンクを切断し、通信を終了する
soc.close();
} catch (IOException ioe) {
// 例外処理
// API がスローするIOException、ConnectionException の処理を行う
}
| |
これで、下記のようなカードの交換を実現することができた。
card_send → server_recv
server_send → card_recv
| |
Copyright © ITmedia, Inc. All Rights Reserved.