今回はWindows環境でグラフィカルにモニタリングできる仕掛けを作ります。
画面描画にはJavaFXが便利なので、jrubyfxというRubyWrapperを使ってみます。
準備
Java(JDK)をインストール
Oracleダウンロードサイト
私の場合は、「jdk-8u45-windows-x64.exe」を選択
JRubyをインストール
JRubyダウンロードサイト
私の場合は、x64(exe)を選択。この当時の最新バージョンは9.0.0.0.pre1。
仕様するgemをインストール
今回は、RubyからPing等を使えるようになるnet-pingを使います。
jgem install net-ping
jgem install win32-security
jgem install jrubyfx
jgemはJRubyのgemです。コマンドプロンプトから実行します。
コーディング
ハマったポイントをご紹介します。
JRubyでNet::Ping::Externalは動かない
net-pingのソースコードを見たらわかるのですが、残念ながらExternalクラスはJVMをサポートしていません。
JRubyでNet::Ping::ICMPを使う場合、管理者権限が必要
考えると当たり前なのですが、直接RawIPSocketを作ることになるため、一般ユーザで実行できません。権限を与えても良いかもしれませんが、今回は見送りました。
Net::Ping::HTTPを使う
実は、単にRTT値が欲しかっただけなのですが、HTTPのレスポンスでもいいかな?ということに途中で気づきまして、これを採用しました。
コードで書くと以下のようになります。
require 'net/ping'
def sendping
server = 'scanme.nmap.org'
@pinger = Net::Ping::HTTP.new(server, timeout = 1)
if @pinger.ping?
rtt_value = @pinger.duration
else
rtt_value = 9999
end
end
durationは、通信開始時間と通信終了時間の差が秒単位(小数点以下第三位まで)で入ります。通信プロトコル上のRTTではなく、アプリケーションから見た時のRTTが入っています。(経験的に100~200msくらい上乗せされています)
この関数を定期的に実行しながら、変化するrtt_valueを使ってグラフィカルに画面描画していくようにします。具体的には、jrubyfxのplay(名前は何でもよいですが)関数で以下のように書きます。以下の例は、2秒おきに実行します。
def play
sendping
handler = EventHandler.impl { |n, e| sendping }
time = Timeline.new
time.cycle_count = :indefinite
time.keyFrames << KeyFrame.new(2000.ms, handler)
time.play
end
あとは、rtt_valueによって絵が変わるように、JavaFXの仕掛けを使って描画です。
ifとelseの繰り返しなので、割愛します。