1
|
1 \chapter{TreeVNC のリファクタリング}
|
|
2
|
|
3 \section{動的な port 番号の指定}
|
|
4 TreeVNCは複雑な分散アルゴリズムを用いたシステムであり、
|
|
5 デバッグを行う環境を整える必要がある。
|
|
6
|
|
7 従来のTreeVNCでは、固定port番号を複数利用していた。
|
|
8 port番号は一意なので、1台で複数のTreeVNCを立ち上げることができない。
|
|
9
|
|
10 動的にport番号を割り当てることで、
|
|
11 1つのnodeに対して複数のTreeVNCを起動することを可能にした。
|
|
12 最低限のソケットポートを開けることによって、
|
|
13 メモリの使用量を抑えることにも繋がる。
|
|
14
|
6
|
15 以下に、動的に port 番号を割り当てているソースコード\ref{selectport}を記述する。
|
4
|
16
|
|
17
|
6
|
18 \begin{lstlisting}[caption=動的な port 番号の割り当て,label=selectport]
|
4
|
19 public int selectPort(int p) {
|
|
20 int port = p;
|
|
21 while (true) {
|
|
22 try {
|
|
23 servSock = new ServerSocket(port);
|
|
24 acceptPort = port;
|
|
25 myAddress = "127.0.0.1";
|
|
26 nets.getNetworkInterfaces();
|
|
27 break;
|
|
28 } catch (BindException e) {
|
|
29 port++;
|
|
30 continue;
|
|
31 } catch (SocketException e) {
|
|
32 e.printStackTrace();
|
|
33 } catch (IOException e) {
|
|
34 e.printStackTrace();
|
|
35 }
|
|
36 }
|
|
37 System.out.println("accept port = " + port);
|
|
38 return port;
|
|
39 }
|
|
40 \end{lstlisting}
|
|
41
|
6
|
42 \newpage
|
4
|
43
|
6
|
44
|
|
45 selectPort メソッドは、TreeVNC を立ち上げた際に呼ばれる。
|
|
46 ソースコード\ref{selectport}の try 節で ServerSocket を生成する。
|
|
47 ServerSocket 生成の際に port 番号を結びつける。
|
|
48 この時に既に port 番号が使用されている場合、
|
|
49 BindException error が起こる。
|
|
50 その場合、catch 節に処理が移行する。
|
|
51 port をインクリメントし、
|
|
52 continue でもう一度 ServerSocket を生成しに行く。
|
|
53 成功するまで port はインクリメントされるので、
|
|
54 ユニークな port 番号を使用することが可能となる。
|
|
55
|
1
|
56 以前は固定port番号を使用しmessageの通信を行っていたが、
|
|
57 一意なportを割り当てられているnodeが通信を行うことによって、
|
|
58 どのport番号が使用されているかを意識する必要がなくなった。
|
|
59
|
|
60
|
3
|
61 \section{QUALITYモードとSPEEDモード}
|
|
62
|
|
63 高解像度のまま拡大・縮小の処理を行うと、
|
|
64 PCのスペックによって描画処理に時間がかかってしまうことがある。
|
|
65 授業中に TreeVNC を使用する際、
|
|
66 拡大・縮小をしてしまうと描画処理が重くなり遅延が生じていた。
|
|
67
|
|
68 画像描画処理には、品質優先( QUALITY モード)・スピード優先( SPEED モード)がある。
|
|
69 今まで TreeVNC は基本的に QUALITY モードを設定していた。
|
|
70
|
|
71 どちらのモードを使用するかをビューワから変更出来るようにした。
|
|
72 これにより、描画処理の遅延を解決することができた。
|
1
|
73
|
|
74
|
4
|
75 \section{ホスト切り替え時の挙動の修正}
|
|
76 画面の切り替えを行う際、新しいホスト側の画面に生じた
|
|
77 ビデオフィードバックが他のユーザに配信されてしまう問題があった。
|
|
78
|
|
79 ホストの切り替えの際、
|
|
80 新しいホスト側のviewerを閉じることで問題を解決した。
|
|
81
|
|
82
|
|
83 \newpage
|
|
84
|
|
85
|
1
|
86 \section{Tree の構成の変更}
|
|
87
|
|
88 従来のTreeVNCは、クライアントの接続する木構造が単一であった。
|
|
89 そのため、ネットワークインターフェースが違うクライアントが
|
|
90 同じ木に混在している状況が生じた。
|
|
91 速度の遅いクライアントが木に存在すると、
|
|
92 そのクライアント以下の通信速度が遅くなってしまう。
|
|
93
|
|
94 この問題を解決するために、
|
|
95 図\ref{fig:multinetworktree}の様に、ネットワークインターフェース別に
|
|
96 木構造を形成するように設計した。
|
|
97
|
|
98 \begin{figure}[htpd]
|
|
99 \begin{center}
|
6
|
100 \includegraphics[scale=0.6]{./images/chapter3/MultiNetworkTree.pdf}
|
1
|
101 \end{center}
|
|
102 \caption{Multi Network Tree}
|
|
103 \label{fig:multinetworktree}
|
|
104 \end{figure}
|
|
105
|
6
|
106 TreeVNC は、root が TreeManager というオブジェクトを持っている。
|
|
107 TreeManager は TreeVNC の接続部分を管理している。
|
|
108 TreeManager では木構造を管理する nodeList が生成される。
|
|
109 この nodeList を元に、新しい node の接続や、node の切断検出時の接続の切り替え等を行う。
|
|
110
|
|
111 今回 TreeManager を、 root の保持しているネットワークインタフェース毎に
|
|
112 生成する様に変更した。
|
|
113 ソースコード\ref{createtreemanager}に、nodeList を生成する部分を示す。
|
|
114
|
|
115 \newpage
|
|
116
|
|
117 \lstinputlisting[breaklines=true,caption=TreeManager の生成,label=createtreemanager]{source/GetNetworkInterfaces.java}
|
|
118
|
|
119 \begin{itemize}
|
|
120 \item for 文を使用し root が所持しているネットワークインタフェースを取得する(\ref{createtreemanager}中, 2行目)
|
|
121 \item その中から、起動しており Multicast に対応しており、また、ループバックインタフェースでないネットワークインタフェースを取得する(\ref{createtreemanager}中, 4行目)
|
|
122 \item 取得してきたネットワークインタフェースの、ネットマスク、ホストネームを取得する(\ref{createtreemanager}中, 6,7行目)
|
|
123 \item TreeManager を生成する(\ref{createtreemanager}中, 8行目)
|
|
124 \item TreeManager にネットマスクとネットアドレスを追加する(\ref{createtreemanager}中, 14行目)
|
|
125 \item HashMap である interfaces に ネットワークインタフェースと対応する TreeManager を追加する(\ref{createtreemanager}中, 15行目)
|
|
126 \end{itemize}
|
|
127
|
|
128 新しい node が接続してきた際、
|
|
129 interfaces から node のネットワークインタフェースと一致する TreeManager を取得する。
|
|
130 その TreeManager に、node 接続の処理を任せる。
|
|
131
|
|
132 こうすることによって、TreeVNC を複数のネットワークインターフェース別に
|
|
133 木構造を構成することができる。
|
|
134
|
|
135
|
|
136
|
1
|
137
|
3
|
138 \newpage
|
|
139
|
1
|
140 \section{切断時の検知方法の変更}
|
|
141
|
3
|
142 接続していたクライアントとの接続が切れた際の検知方法を変更した。
|
|
143
|
|
144 root は nodeList という TreeVNC のネットワークトポロジーを管理するためのリストを持っている。
|
|
145 root は TreeVNC の接続処理の全てを担っている。
|
|
146 %node が切断された場合、 root は TreeVNC の木構造を崩さないように切断を検知し、
|
|
147 %木構造を崩さないよう、 node 同士の接続を再構成しなければならない。
|
|
148 node の接続が切れた場合、代わりとなる node の接続が必要となるため root に知らせなければならない。
|
|
149
|
|
150 変更前は、lostParent という検知方法を採用していた。
|
|
151 この方法は、親となる node の接続が切れた場合、
|
|
152 子となる node から root に対して lostParent message を送信する。
|
|
153 これにより root は lostParent を検知し、代替 node の接続を行う。
|
|
154
|
4
|
155 以下に、lostParent の検知・再接続方法を記述する。
|
|
156
|
|
157 \begin{itemize}
|
|
158 \item 親 node の接続が切れる
|
|
159 \item 切れた親 node に接続していた子 node が root に LOST\_PARENT message を送信する
|
|
160 \item root が nodeList の更新を行う
|
|
161 \item 切れた親 node の代わりに、nodeList の最後尾 node を配置する
|
|
162 \item 親 node を失った子 node は、新しい親 node に接続する
|
|
163 \end{itemize}
|
|
164
|
3
|
165 この方法では、子のいない末端の node の接続が切れた際に root にメッセージが送信されない。
|
|
166 root は切断を検知できないと、nodeList の更新を行うことができない。
|
|
167 nodeList が正しく更新されない場合、図\ref{fig:lostparent}のように、
|
|
168 新しい node を既に切断されている node に接続しようと試み、失敗してしまう。
|
1
|
169
|
|
170 \begin{figure}[htpd]
|
|
171 \begin{center}
|
3
|
172 \includegraphics[scale=0.7]{./images/chapter3/lostParent.pdf}
|
1
|
173 \end{center}
|
|
174 \caption{lostParent}
|
|
175 \label{fig:lostparent}
|
|
176 \end{figure}
|
|
177
|
4
|
178 \newpage
|
|
179
|
3
|
180 末端 node の切断が検知できない問題を解決するために、
|
|
181 lostChild という検知方法に変更した。
|
|
182
|
4
|
183 TreeVNC は、画像データ(framebufferUpdate)が MulticastQueue という Queue に蓄積される。
|
3
|
184 node はこの Queue から画像データを取得し、描画している。
|
|
185 lostChild の検出方法は、この MulticastQueue を使用している。
|
|
186 ある一定時間、MulticastQueue から画像データが取得されない場合、
|
4
|
187 その node との接続が切れたと判断することができる。
|
|
188
|
|
189 以下に、lostChild の検知・再接続方法を記述する。
|
3
|
190
|
4
|
191 \begin{itemize}
|
|
192 \item 子 node の切断を検知した node が root へ LOST\_CHILD message を送信する(図\ref{fig:lostchild1}中, 1:)
|
|
193 \item LOST\_CHILD message を受け取った root は nodeList の更新を行う(図\ref{fig:lostchild1}中, 2:)
|
|
194 \item 切断した node を nodeList から消し、nodeList の最後尾の node に切断した node number を割り当てる
|
|
195 \item root は最後尾の node に、切断した子 node が接続していた親 node に接続する様に CONNECT\_TO message を送信する(図\ref{fig:lostchild1}中, 3:)
|
|
196 \item 最後尾の node が子 node を失った親 node へ接続しに行く(図\ref{fig:lostchild1}中, 4:)
|
|
197 \end{itemize}
|
3
|
198
|
1
|
199 \begin{figure}[htpd]
|
|
200 \begin{center}
|
3
|
201 \includegraphics[scale=0.7]{./images/chapter3/lostChild1.pdf}
|
1
|
202 \end{center}
|
3
|
203 \caption{lostChild を検知・再接続}
|
1
|
204 \label{fig:lostchild1}
|
|
205 \end{figure}
|
|
206
|
4
|
207 \newpage
|
|
208
|
|
209 lostChild を検知することより、
|
|
210 切断されてしまった全ての node を検知することができるので、
|
|
211 nodeList の更新が正しく行われる。
|
|
212
|
|
213 新しい node からの接続要求 WHERE\_TO\_CONNECT message に対して、
|
|
214 適切な node への接続を提供することができる(図\ref{fig:lostchild2}中, 1,2:)。
|
|
215
|
1
|
216 \begin{figure}[htpd]
|
|
217 \begin{center}
|
3
|
218 \includegraphics[scale=0.7]{./images/chapter3/lostChild2.pdf}
|
1
|
219 \end{center}
|
3
|
220 \caption{新 node の接続}
|
1
|
221 \label{fig:lostchild2}
|
|
222 \end{figure}
|
|
223
|