Natural Style Co. Ltd.

~ それ、やってみよう / Let's try it ~

OCNトップに「人生ゲームTOWN」が登場!

毎日ルーレットを回して素敵な人生を謳歌しよう。
あなたはあの職に就けるかな?

あの「黒ひげ危機一発」が遂にiPhoneで登場!
刺して、飛ばして、そして今回は黒ひげ君をキャッチ! 黒ひげ君のお宝をいただいて、目指せお宝コンプリート!!
更にたるの最大穴数が50000穴の「世界黒ひげ」も同時収録! 「黒ひげキャッチ危機一発」で世界剣をGETして 世界中のみんなと黒ひげ君を助けよう!

東京ゲームショーにて「黒ひげキャッチ危機一発」を展示しています!

「刺して」「飛ばして」「キャッチして」!
お宝ゲットに世界進出!?

会場にお越しの際はぜひご体感ください!

簡単そうで意外とトリッキーだったので記事にしてみます。

VBScript は 日付だろうが時刻だろうが、時間に関するデータは、
1日を1とする数値で保持してるらしい。
なのでTimeSerialとかで作った値をCLngとかにかけると
1とか返ってきて意味わかんないことになる。

日時のシリアル作りたい時、これまではYYYYMMDDHHMMSSみたいな
フォーマットしてたけど、これからはこれでOK!

Real World なコードがブームということで、Haskell のデーモン化のサンプル
を書いてみました。Unix系とWindows系対応です。
https://github.com/mitsuji/hdaemon

ビルド方法等については、READMEを参照。
https://github.com/mitsuji/hdaemon/blob/master/README

サンプルデーモンの仕様は下記のとおり。

* 開始時にログファイルを開いて"start!"を出力
* 2秒毎に"go!"を出力
* 終了時に"stop!"を出力してログファイルを閉じる

[Haskell編]

Haskellのコードをデーモン化するにはまず、Haskellコード単体で
"start" "stop" できるようなサービス化が必要になります。
具体的にはghciからこんな感じで使えるようにすると開発もしやすそうですね。

> :load HDaemon.Server
> h <- start "log0.txt"
> stop h

start 内部で作成してサービスのハンドルとして返すMVarに
実行を継続するか否かの状態を入れておき、serve の再帰呼び出し時に確認、
stop から状態を変更させることで制御しています。

状態が Run|Shutdown|Stop の三値になっているのは、
サービスの終了シーケンスを確実に完了させるためです。

呼び出し元のコンテキストが終了しない ghci の様な環境では
Run|Stop の二値でも一見正常動作するのですが、
通常の環境では、終了シーケンスが完了する前に呼び出し元が終了しないように
stop内部で待つ必要があり、「終了操作中」状態として Shutdown が必要になります。

状態の参照はIORefでも持てるのですが、何となく安心なMVarにしてます。

[Unix(Mac OS X and Linux)編]

HDaemon/Server.hs に、下記のコードをリンクします。
posix.c
HDaemon/Daemon.hs

posix.c の main で Haskell のコンテキストを作成し、
HDaemon.Daemon.foreignMain を呼び出しています。

Unix系のOSでプログラムをデーモン化するには、
呼び出し元のプロセスをforkしてデーモン本体となる子プロセスを作成、
子プロセスのプロセスIDを/var/run/xxx.pid に保存、
chdir("/") してから標準入力・標準出力・標準エラーを閉じる
という手順が必要になります。

また、終了シーケンスを呼び出すための TERM のようなシグナルを
受け取れるように、子プロセスの開始時にハンドラを登録しておく必要があります。

デーモンを終了するときには、/var/run/xxx.pid に保存したプロセスID
を使って、どのプロセスにシグナルを送るか判断することになるでしょう。

今回、プロセスの fork については、プロセスIDの保存以外をやってくれる
forkProcess という関数がSystem.Posix.Process に用意されていたのですが
現在のところマルチプロセッサー(コア)に対応していないとのことで、
今回は同様の機能を提供してくれる unistd.h の daemon() を使って
C言語で実装することにしました。

C言語の main のパラメータをそのまま hs_init に渡しているので
+RTS -N のようなパラメータも、指定すればHaskellのコンテキストに渡されるはずです。

シグナルについては System.Posix.Signals に installHandler という、
シグナルハンドラをHaskellで定義できる非常に便利な関数が
用意されていたので、こちらを使うことにしました。


[Windows編]

HDaemon/Server.hs に、下記のコードをリンクします。
win32.c
HDaemon/Foreign.hs

HDaemon/Foreign.hs に、C言語から呼び出せるようにした
HDaemon.Server.start HDaemon.Server.stop のラッパー
(HDaemon.Foreign.foreignStart, HDaemon.Foreign.foreignStop)
を用意し、これを win32.c の Windowsサービスから呼び出しています。

Windows の場合はサービスの仕組みにHaskellが入り込む余地はないようなので
HaskellのサービスのハンドルをC言語のポインタとして参照できるようにして、
一般的なWindowsサービスのサンプルコードを元に作成したコードから呼び出す
ようにしました。

Haskell側でハンドルを Foreign.StablePtr でラップしてやると
C言語側で HsStablePtr として参照を保持することが出来るようです。

hs_init にパラメータを渡すために、Windows側で提供されているスマートな方法を
探したのですが見つからず、main の argv をグローバル変数に保存しておき、
Haslellコンテキスト作成時に参照するというトリッキーなコードになっていますが
一応想定したような動作はしてくれるようです。

※Windows の C言語のコードは無意味に長すぎるので割愛します。

[感想]

Haskell初心者な上に、デーモン化(Unix)もサービス化(Windows)も
前提知識が乏しかったので少し時間はかかったけど意外と簡単にできたと思います。

System.Posix.Signals.installHandler 見つけたときは感動しました。
あとは System.Posix.Process.forkProcess がマルチコア対応したら、
Unix版は Haskellだけで完結できると思います。

Foreign.StablePtr とか使うと何でもできそうな気がしてきますが、
FFIはなるべく使いたくないなー。

あとは、せっかくHaskellやってるのに、命令型っぽいコードばかり書いてる
感じになっちゃってるのが少し悲しいです。。。

自分への要望。
* restart 動作も実装したい。
* Unix版でpidファイルのpathを指定できるようにしたい。
* Windows版で実行中に他のプロセスからログが読み取れないのが気になる。
(ファイルの読み取りモード指定もっと細かくできるのかな?)

この辺りは具体的なサービスを書くときに対応されていくことでしょう。
さーて、ghc はネイティブコードはくし、グリーンスレッド使い放題やし、
Haskellで何つくろうかなー。

イソップ童話「王様の耳はロバの耳」に登場する井戸のように あなたのつぶやきをたくさんの人と共有する。 それがロバ耳です。

ロバ耳はあなたの声をたくさんの人に届けます。 また、たくさんの人の声があなたに届きます。

たくさんの声たちはすべて生声でお送りします。

叫んでも、ぼそっとつぶやいてもかまいません。 その時々に思ったことを、感情豊かに発信してください。

だけど童話のように秘密をつぶやいてはいけませんよ?


android 2.3.3 以降対応

画面をタッチして音を出してみよう!
♦「いきもの」
色々な動物の声が聞けるよ!写真をタッチしてみよう!

♦「せいかつ」
身近にある色々な音が聞けるよ!

♦「メロディ」
音が楽しめるよ!スタートボタンを押して光ったところをタッチしてみよう! リズムにのって音を出すと聞いたことのあるメロディになるかも?

早速タッチして音を体験してみてください。

お絵描きが楽しめる玩具「せんせい」を再現したアプリ「iせんせい」になんとあの「はなかっぱ版」が登場。 エリアによって何色も楽しめる「カラフル」仕様。 左にいる はなかっぱ は実は・・・。 描いた絵を「みんなのはなかっぱ×iせんせい」サイトにアップロードすることができます。 花さけ!パッカ~ん♪

Naspがバージョンアップしました。
  

[更新履歴]

  • ‘application/x-www-form-urlencoded’ が ezweb で動作しない不具合対処

前回のバージョンアップ時に対応した機能に不具合が見つかり、対処いたしました。
ご迷惑をおかけし申し訳ございませんでした。

今後ともNSWareをよろしくお願い致します。

端末情報ファイルが更新されました。
  Version: 20110527
  

下記のUserAgentが追加されています。

  • DoCoMo/2.0 F08C
  • DoCoMo/2.0 SH10C
  • DoCoMo/2.0 SH11C
  • KDDI-SN3T
  • SoftBank/1.0/002P
  • SoftBank/1.0/002Pe

端末情報「Environments」のご利用には
ライセンス料をお支払いくださいますようお願いいたします。

NSWareをよろしくお願いいたします。