view chapter3.tex @ 8:42b6994eac80

update chapter2
author oc
date Tue, 17 Feb 2015 04:17:26 +0900
parents f6b14e3b72e0
children 034ad3cd49df
line wrap: on
line source

\chapter{TreeVNC のリファクタリング}

\section{動的な port 番号の指定}
TreeVNC は複雑な分散アルゴリズムを用いたシステムであり、
デバッグを行う環境を整える必要がある。

従来の TreeVNC は、メッセージ通信の際に固定 port 番号を複数利用していた。
port 番号は一意なので、1台で複数の TreeVNC を立ち上げることができなかった。

今回、動的に port 番号を割り当てることで、
1つの PC で複数の TreeVNC を起動することを可能にした。
そして、最低限のソケットポートを開けることによって、
メモリの使用量を抑えることにも繋がった。

以下に、動的に port 番号を割り当てているソースコード\ref{selectport}を記述する。


\begin{lstlisting}[caption=動的な port 番号の割り当て,label=selectport]
    public int selectPort(int p) {
        int port = p;
        while (true) {
            try {
                servSock = new ServerSocket(port);
                acceptPort = port;
                myAddress = "127.0.0.1";
                nets.getNetworkInterfaces();
                break;
            } catch (BindException e) {
                port++;
                continue;
            } catch (SocketException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        System.out.println("accept port = " + port);
        return port;
    }
\end{lstlisting}

\newpage

selectPort メソッドは、TreeVNC を立ち上げた際に呼ばれる。
ソースコード\ref{selectport}の try 節で ServerSocket を生成する。
ServerSocket 生成の際に port 番号を結びつける。
この時、既に port 番号が使用されている場合、
BindException error が起こる。
その場合、catch 節に処理が移行する。
catch 節では port をインクリメントし、
continue でもう一度 ServerSocket を生成する try 節に戻る。
成功するまで port はインクリメントされるので、
ユニークな port 番号を使用することが可能となる。

以前は固定 port 番号を使用し message の通信を行っていたが、
一意な port を割り当てられている node が通信を行うことによって、
通信の際にどの port 番号が使用されているかを意識する必要がなくなった。


\section{QUALITY モードと SPEED モード}

高解像度のまま拡大・縮小の処理を行うと、
PC のスペックによって描画処理に時間がかかってしまうことがある。

画像描画処理には、
高画質優先の QUALITY モードと描画速度優先の SPEED モードがある。
今まで TreeVNC は QUALITY モードで使用していた。

しかし、授業中に TreeVNC を使用する際、
拡大・縮小をしてしまうと描画処理が重くなり遅延が生じていた。

今回、どちらのモードを使用するかをビューワから変更出来るようにした。
これにより、描画処理の遅延を解決することができた。


\section{ホスト切り替え時の挙動の修正}
画面の切り替えを行う際、新しいホスト側の画面に生じた
ビデオフィードバックが他のユーザに配信されてしまう問題があった。

ホストの切り替えの際、
新しいホスト側のviewerを閉じることでこの問題を解決した。


\newpage


\section{Tree の構成の変更}

従来の TreeVNC は、クライアントの接続する木構造が単一であった。
そのため、ネットワークインターフェースが違うクライアントが
同じ木に混在している状況が生じた。
速度の遅いクライアントが木に存在すると、
そのクライアント以下の通信速度が遅くなってしまう。

この問題を解決するために、
図\ref{fig:multinetworktree}の様に、ネットワークインターフェース別に
木構造を形成するように設計した。

\begin{figure}[htpd]
  \begin{center}
    \includegraphics[scale=0.6]{./images/chapter3/MultiNetworkTree.pdf}
  \end{center}
  \caption{Multi Network Tree}
  \label{fig:multinetworktree}
\end{figure}

TreeVNC は、root が TreeManager というオブジェクトを持っている。
TreeManager は TreeVNC の接続部分を管理している。
TreeManager では木構造を管理する nodeList が生成される。
この nodeList を元に、新しい node の接続や、node の切断検出時の接続の切り替え等を行う。

今回、root の保持しているネットワークインタフェース毎に
TreeManager を生成する様に変更した。
ソースコード\ref{createtreemanager}に、nodeList を生成する部分を示す。

\newpage

\lstinputlisting[breaklines=true,caption=TreeManager の生成,label=createtreemanager]{source/GetNetworkInterfaces.java}

\begin{itemize}
  \item for 文を使用し root が所持しているネットワークインタフェースを取得する(\ref{createtreemanager}中, 2行目)
  \item その中から、起動しており Multicast に対応しており、また、ループバックインタフェースでないネットワークインタフェースを取得する(\ref{createtreemanager}中, 4行目)
  \item 取得してきたネットワークインタフェースの、ネットマスク、ホストネームを取得する(\ref{createtreemanager}中, 6,7行目)
  \item TreeManager を生成する(\ref{createtreemanager}中, 8行目)
  \item TreeManager にネットマスクとネットアドレスを追加する(\ref{createtreemanager}中, 14行目)
  \item HashMap である interfaces に ネットワークインタフェースと対応する TreeManager を追加する(\ref{createtreemanager}中, 15行目)
\end{itemize}

新しい node が接続してきた際、
interfaces から node のネットワークインタフェースと一致する TreeManager を取得する。
その TreeManager に、node 接続の処理を任せる。

こうすることによって、TreeVNC を複数のネットワークインターフェース別に
木構造を構成することができる。




\newpage

\section{切断時の検知方法の変更}

接続していたクライアントとの接続が切れた際の検知方法を変更した。

root は nodeList という TreeVNC のネットワークトポロジーを管理するためのリストを持っている。
root は TreeVNC の接続処理の全てを担っている。
%node が切断された場合、 root は TreeVNC の木構造を崩さないように切断を検知し、
%木構造を崩さないよう、 node 同士の接続を再構成しなければならない。
node の接続が切れた場合、代わりとなる node の接続が必要となるため root に知らせなければならない。

変更前は、lostParent という検知方法を採用していた。
この方法は、親となる node の接続が切れた場合、
子となる node から root に対して lostParent message を送信する。
これにより root は lostParent を検知し、代替 node の接続を行う。

以下に、lostParent の検知・再接続方法を記述する。

\begin{itemize}
  \item 親 node の接続が切れる
  \item 切れた親 node に接続していた子 node が root に LOST\_PARENT message を送信する
  \item root が nodeList の更新を行う
  \item 切れた親 node の代わりに、nodeList の最後尾 node を配置する
  \item 親 node を失った子 node は、新しい親 node に接続する
\end{itemize}

この方法では、子のいない末端の node の接続が切れた際に root にメッセージが送信されない。
root は切断を検知できないと、nodeList の更新を行うことができない。
nodeList が正しく更新されない場合、図\ref{fig:lostparent}のように、
新しい node を既に切断されている node に接続しようと試み、失敗してしまう。

\begin{figure}[htpd]
  \begin{center}
    \includegraphics[scale=0.7]{./images/chapter3/lostParent.pdf}
  \end{center}
  \caption{lostParent}
  \label{fig:lostparent}
\end{figure}

\newpage

末端 node の切断が検知できない問題を解決するために、
lostChild という検知方法に変更した。

TreeVNC は、画像データ(framebufferUpdate)が MulticastQueue という Queue に蓄積される。
node はこの Queue から画像データを取得し、描画している。
lostChild の検出方法は、この MulticastQueue を使用している。
ある一定時間、MulticastQueue から画像データが取得されない場合、
その node との接続が切れたと判断することができる。

以下に、lostChild の検知・再接続方法を記述する。

\begin{itemize}
  \item 子 node の切断を検知した node が root へ LOST\_CHILD message を送信する(図\ref{fig:lostchild1}中, 1:)
  \item LOST\_CHILD message を受け取った root は nodeList の更新を行う(図\ref{fig:lostchild1}中, 2:)
  \item 切断した node を nodeList から消し、nodeList の最後尾の node に切断した node number を割り当てる
  \item root は最後尾の node に、切断した子 node が接続していた親 node に接続する様に CONNECT\_TO message を送信する(図\ref{fig:lostchild1}中, 3:)
  \item 最後尾の node が子 node を失った親 node へ接続しに行く(図\ref{fig:lostchild1}中, 4:)
\end{itemize}

\begin{figure}[htpd]
  \begin{center}
    \includegraphics[scale=0.7]{./images/chapter3/lostChild1.pdf}
  \end{center}
  \caption{lostChild を検知・再接続}
  \label{fig:lostchild1}
\end{figure}

\newpage

lostChild を検知することより、
切断されてしまった全ての node を検知することができるので、
nodeList の更新が正しく行われる。

新しい node からの接続要求 WHERE\_TO\_CONNECT message に対して、
適切な node への接続を提供することができる(図\ref{fig:lostchild2}中, 1,2:)。

\begin{figure}[htpd]
  \begin{center}
    \includegraphics[scale=0.7]{./images/chapter3/lostChild2.pdf}
  \end{center}
  \caption{新 node の接続}
  \label{fig:lostchild2}
\end{figure}