Java による授業向け画面共有システムの設計と実装

  • 大城 信康 谷成 雄
  • 琉球大学 並列信頼研究室

    目的と背景

  • 大学の講義中、スクリーンに映されている画面は後ろの席程見えずらい。
  • その問題を手元のPCにも写せるようにすることで解決しようと考えた。
  • 60人以上での画面共有を行うことを目標とする。
  • VNCを用いての画面共有

  • 画面を共有する方法 -> VNC
  • VNC: Virtual Network Computing
    ネットワークを介してコンピュータを遠隔操作するプログラム
  • VNCのリモートPCの画面を写す機能を利用する。
  • 通常のVNCの問題点

  • VNC Serverの負荷が重い。
  • Server側の通信網1本への通信負荷が高い。
  • 通常のVNCの問題点

  • 1台と48台でVNCをかけた時のスループットとサーバ側のCPU使用率
  • スループット(単位:Byte) CPU使用率
    1台 20M 15%
    48台 0.4M 100%
  • VNCに使われるCPUの使用率が100%になり、スループットが5分の1まで下がっている。
  • VNCの問題点の解決策

    クライアントを木構造で接続させる

    TreeVNCの利点

  • クライアントが増えてもかかる負荷一定。
  • 通信網1本に対する負荷が減り、安定した通信ができる(有線)。
  • 通常のVNC TreeVNC

    TreeVNCの設計

  • TreeVNCのクライアントは最初にTop Proxyに接続を行う。
  • データは木の下へと流していく。
  • tightVNC ViewerのJava版(ver 1.3)を元にTreeVNCの実装を行う。
  • 発表内容

    RFB protocol

  • Remote Frame Buffer Protocol :
    GUI操作によるリモートアクセス用の通信プロトコル。VNCで用いられる。
  • 転送される画面(フレームバッファ)のデータは変更があった部分(差分)だけが矩形単位で送られる。
  • で囲まれている矩形のデータだけが送られてくる。

    VNC のシーケンス図

  • 1~5まではinitial seaquenceとなる。
  • 6以降は繰り返し行われる処理。画面のデータが転送されてくる。
  • RFB Protocol

  • FramebufferUpdateRequestの内容
  • バイト数
    型   [値]
    説明
    1
    U8         3
    message-type
    1
    U8
    incremental
    2
    U16
    x-position
    2
    U16
    y-position
    2
    U16
    width
    2
    U16
    height
    incrementalについて
  • 0の場合、VNC Serverは指定された領域の矩形データを送ってくる。
  • 0以外の場合はその領域内で差分が発生した時に矩形データを送る。
  • RFB Protocol

  • FramebufferUpdate
  • バイト数
    型   [値]
    説明
    1
    U8         0
    message-type
    1
    U8
    padding
    2
    U16
    number-of-rectangles
  • 以下number-of-rectanglesの数だけ矩形のデータが続く
  • 2
    U16
    x-position
    2
    U16
    y-position
    2
    U16
    width
    2
    U16
    height
    4
    U32
    encoding-type

    RFB Protocol

  • 図を入れる
  • 指定された領域の矩形を更新しているのが分かる図
  • RFB Protocol

  • RFB ProtocolにはFramebufferUpdateRequestだけではなく、キーボード・マウスポインタの入力を伝えるkeyEventやPointerEvent等もある。
  • TreeVNCでは画面の共有を行いたいのでそれらのイベントに対しての実装は行っていない。
  • 負荷分散

  • 負荷分散を行う上で重要: -> 転送するデータ量を見積もること
  • ネットワークの帯域やswtichにかかる負荷を把握するため。負荷を把握していないと負荷分散できているかどうかも解らない。
  • RFB Protocolで送られてくるデータ量: -> 先頭の20バイトを読むことで見積もることができる。
  • データ量の見積もり

  • FramebufferUpdate(以下update)毎にデータを扱うためには、update1回分で送られてくるバイト量を知る必要がある
    (どこまで読みこめば終わりなのか知る必要がある)。
  • 先頭の20バイトを読むことでupdate1回分のバイト量を知ることができる(厳密にはエンコード次第だが...)。
  • updateは最初に送られてくる情報に矩形の横と縦幅(width,height)が含まれていてそれと扱われるエンコードによって全体のデータ量を計算することができる。
  • データ量の見積もり

  • ZRLEエンコードの場合
  • 最初の4bitにどれだけのデータ量が送られてくるのかという情報が送られてくる。
  • バイト数
    型   [値]
    説明
    4 U32 length
    length U8 array zlibData
    • ZlibDataはgzipされたデータのこと

    データ量の見積もり

  • 先頭20バイトを読みupdate一回分のデータ量を調べる。
  • update1回分のデータを読み込み次のクライアントに送信する。
  • また、描画データを送信すると同時に画面の更新を行うようにする。
  • 描画データの管理はMulticastQueueで行った。
  • MulticastQueue

  • MulticastQueueはjava.util.CountDownLatchを用いて実装されたクラスである。
  • クライアントから接続されると、データ転送用のスレッド(sender)が走る。
  • このスレッドは次に流すデータが来るまでは待機して置かなければならない。そして流すべきデータがくるとまた動き始めなければならない。
  • このスレッドの待機・解放を行うのがMulticastQueueとなる。
  • MulticastQueue

  • MulticastQueueの図を入れる。
  • 接続されてきた時点からデータの送信が始まる。データは読み込まれるまでメモリ上に残っている。

    MulticastQueueの問題点

  • Clientがデータを読み込まないとデータが溜まりメモリを圧迫してしまう。
  • MulticastQueueの問題点

  • 解決策
  • TimeOut(TO)スレッドを走らせ、一定の時間データを読み込まなければ代わりにこのTOが読み込むようにする。
  • TreeVNCのデモ

  • では実際に動かしてみる。
  • エンコードの問題 

  • ZRLE : Zlib Run-Length Encoding

  • データをZlib圧縮扱うエンコーディング。
    Macintoshでもこのエンコードは使うことができる。
  • Rawエンコードより約1/8倍少ないデータ量ですむ。
  • 解凍器(Deflater)は辞書を持っていて、その辞書を元に解凍を行う。
  • この辞書を吐き出す(flush)する機能がJavaにはなかった。
  • ZRLEの問題

  • 解凍に必要な辞書を取り出すことができないため、ZRLEのデータはそのまま投げるだけでは正しく解凍されない。
  • そこで、VNC Serverへ接続するTop ProxyはZRLEで送られてきたデータを毎回新しく圧縮し直すという方法をとった。
  • 一度圧縮し直されたデータはそのまま流すことができる。よってクライアント側では圧縮し直す必要はない。
  • このエンコードはZRLEE(Economy)として扱うことにした。
  • TreeVNCの利点と欠点

    テスト環境について

  • CUI版のVNCクライアントを作成
  • 48台あるクラスタでCUI版のクライアントをはしらせてVNCをかけさせる。
  • 最初の1台目と50台めをGUI版のクライアントで接続を行い見比べてみる。
  • 既存のプログラムとの比較

  • VNC Reflector