著作一覧 |
必要がでてきて、ちょっと考えた。
たとえば、定期的に何かする静かなアプリケーション(UIと言えばタスクバーの通知領域にアイコンがあって、たまに「エラーになってるからログ見てくれ」とか吹き出しが出る程度のやつ)が今何してるか知りたいとする。
クライアントは、HTAとかだよな、やっぱり、と考える。
すると逆向きCOM Interopってのが候補に挙がる。
が、なんか違う気がする。大体、後からノートPCをHubに差し込んで調べるというようなこと考えると、危険極まりないDCOMの利用になってしまう。それは、最悪の場合に最悪の事態となる。
ではRemotingって……相変わらずVisual Studioのサポートないのか。却下だ。
Webサービス……「追加」からは選べないな。
で、System.Net.HttpListenerを使うことになる。
使い方は簡単。送信情報に秘匿すべきものがなければ、ほとんど何も考える必要すらない。エフェメラルポートの衝突は怖いけど(ないわけじゃないんだな、これが)、まあ、多少のリスクは抱えてもしょうがないと割り切る。(追記:80でも良いのだがなんとなく別にしたい)
ただ、ワーカースレッドとか勝手に作ってくれないし、基本は一発勝負型なので自分で再要求したりしないといけない。最初、ちょびっとはまった。(続く)
using System.Threading; public class Counter { volatile bool stop; volatile int counter; public void Service() { while (!stop) { counter++; Thread.Sleep(10000); } } public static void Main() { Counter c = new Counter(); c.Service(); } }このプログラムが、外部のプログラムに現在のカウンター値を教えるようにできることと、いざとなったらきれいに終わらせられるようにすることがやりたいことだ。
using System; using System.IO; using System.Net; using System.Text; using System.Threading; public class Counter { volatile bool stop; volatile int counter; volatile HttpListener listener; public Counter() { listener = new HttpListener(); listener.Prefixes.Add("http://*:9020/counter/"); listener.IgnoreWriteExceptions = true; listener.Start(); Listen(); // 再実行するので別メソッドにしておく } void Listen() { listener.BeginGetContext(delegate (IAsyncResult ar) { if (stop) { return; } Listen(); // 次のリクエストを受け付けるようにする HttpListenerContext lc = listener.EndGetContext(ar); lc.Response.ContentType = "text/xml"; TextWriter w = new StreamWriter(lc.Response.OutputStream, Encoding.UTF8); w.WriteLine("<?xml version=\"1.0\"?>"); w.WriteLine("<Counter>"); w.WriteLine(" <value>" + counter + "</value>"); w.WriteLine("</Counter>"); w.Close(); // MSDNのサンプルだとCloseを呼んでるので真似。 if (lc.Request.Url.Segments[lc.Request.Url.Segments.Length - 1] == "quit") // C#とJavaの最大の差 { stop = true; } lc.Response.Close(); }, this); } public void Service() { while (!stop) { counter++; Thread.Sleep(10000); } listener.Stop(); } public static void Main() { if (!HttpListener.IsSupported) { Console.WriteLine("Buy Windows XP SP2 Now !!!"); return; } Counter c = new Counter(); c.Service(); } }これで、http://localhost:9020/counter と呼べば現在のカウンター値を参照できるし、http://localhost:9020/counter/quit と呼べば実行を終了できる(最大10秒待たされるけど)。
ジェズイットを見習え |
JMX使うのが一番便利かな〜と。
サンプルソースきぼんぬ。