このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。
これでクライアントメッセージが全て揃ったので、
クライアントの送るメッセージを解析する事ができる。
まず、クライアントメッセージを読み出して、
ClientMessage 実装インスタンスを返すメソッドを作る。
例によって RFBSession クラスに追加しよう。
========== RFBSession#getClientMessage ==========
private ClientMessage getClientMessage(
RFBContext context, RFBInputStream in) throws IOException {
// 1 バイト先読み
in.mark(1);
int type = in.readU8();
in.reset();
// 上限境界ワイルドカードによる限定
Class<? extends ClientMessage> messageClass;
switch (type) {
case ClientMessage.SET_PIXEL_FORMAT:
messageClass = SetPixelFormatMessage.class;
break;
case ClientMessage.FIX_COLOR_MAP_ENTRIES:
messageClass = FixColorMapEntriesMessage.class;
break;
case ClientMessage.SET_ENCODINGS:
messageClass = SetEncodingsMessage.class;
break;
case ClientMessage.FRAMEBUFFER_UPDATE_REQUEST:
messageClass = FramebufferUpdateRequestMessage.class;
break;
case ClientMessage.KEY_EVENT:
messageClass = KeyEventMessage.class;
break;
case ClientMessage.POINTER_EVENT:
messageClass = PointerEventMessage.class;
break;
case ClientMessage.CLIENT_CUT_TEXT:
messageClass = ClientCutTextMessage.class;
break;
default:
throw new IOException("unknown client message.");
}
return in.readMessage(context, messageClass);
}
========== end of RFBSession#getClientMessage ==========
クライアントメッセージの読み込みは、
RFBInputStream#readMessage を使えば良いが、
このメソッドは Class 型のインスタンスを要求する。
メッセージ駆動モードに入った後は、
送られるメッセージに規則性がないため、
この時点ではどのメッセージが来るかわからない。
そこで、InputStream#mark を呼び出して位置を記憶し、
readU8 でメッセージの種類だけを先読みする。
そして InputStream#reset を呼び出して位置を戻す。
こうすることでメッセージの種類が分かるので、
後は対応したメッセージの Class を用意し、
改めて RFBInputStream#readMessage を呼び出すと完了となる。
messageClass の型に上限境界ワイルドカードを指定したため、
readMessage を呼び出す際にキャストが全く不要である。
では、RFBSession#processMain を書き換えて、
クライアントメッセージをデバッグ出力するようにしてみよう。
========== RFBSession#processMain ==========
// メイン処理
private void processMain(RFBContext context,
RFBInputStream in, RFBOutputStream out) throws IOException {
// 初期化
{
// (…省略…)
}
// メッセージ駆動モードへ
for (;;) {
// クライアントからメッセージを受け取り
ClientMessage message = getClientMessage(context, in);
// コンソールへ出力
System.out.println(message);
}
}
========== end of RFBSession#processMain ==========
では、実行して RealVNC Viewer で接続してみよう。
まだサーバは何の返事もしないので、
表示される画面は真っ黒のままだが、
画面でキー入力したりマウスを動かしたりすると、
コンソールにごちゃごちゃと情報が表示された。
jp.loafer.rfb.message.client.SetPixelFormatMessage@84ce7a
jp.loafer.rfb.message.client.SetEncodingsMessage@a45536
jp.loafer.rfb.message.client.FramebufferUpdateRequestMessage@164b09c
jp.loafer.rfb.message.client.PointerEventMessage@2b9406
jp.loafer.rfb.message.client.PointerEventMessage@1035079
jp.loafer.rfb.message.client.PointerEventMessage@983d95
jp.loafer.rfb.message.client.PointerEventMessage@f30494
jp.loafer.rfb.message.client.PointerEventMessage@b1cc87
jp.loafer.rfb.message.client.PointerEventMessage@eaf40c
jp.loafer.rfb.message.client.KeyEventMessage@50a649
jp.loafer.rfb.message.client.KeyEventMessage@d507e9
jp.loafer.rfb.message.client.KeyEventMessage@1fa6d18
jp.loafer.rfb.message.client.KeyEventMessage@1049d3
jp.loafer.rfb.message.client.KeyEventMessage@15ed659
jp.loafer.rfb.message.client.KeyEventMessage@14a7a12
jp.loafer.rfb.message.client.KeyEventMessage@9444d1
jp.loafer.rfb.message.client.KeyEventMessage@32060c
toString をオーバライドしていなかったので、
このままではメッセージの内容は分からないが、
ちゃんとメッセージを読めているようだ。