PHPでIPCを行う

■ジュークボックスシステムはサーバー・クライアントに分散される構成なのでプロセス間通信が必須になる。ワークファイルを経由させてもいいけれど、それはそれで後が面倒なので、メッセージキューや共有メモリを使いました。技術的には古いので使っているから殊更なんだと言うものではないですが、実装上のメモとして。

 メッセージキューそのものは方向性を持たない一種のデータバスとして利用できますが、通信プロトコルを持たないので双方向通信はやっかいです。自分で書き込んだメッセージを自分で読み出してしまったりします。なので、クライアント・サーバー間に2本のメッセージキューを用意しました。__construct()の中でキューへのアクセスキーを2つ取得しました。


 $this->keySvTx = ftok(__FILE__, "t");
 $this->keySvRx = ftok(__FILE__, "r");
     :
     :
 $this->hndTx = msg_get_queue($this->keySvTx);
 $this->hndRx = msg_get_queue($this->keySvRx);

 __destruct()の中で、キューをリムーブします。


 $rc = @msg_remove_queue($this->hndRx);
 $rc = @msg_remove_queue($this->hndTx);

 送信・受信では、クライアントからサーバーへの送信には、msgtypeにプロセス番号を割り当てています。サーバーからクライアントへの返信にはmsgtypeにクライアントのプロセス番号を割り当てることで、特定のクライアントが読み出せるようにしました。全クライアントへの同報通信(ブロードキャスト)は実装しませんでした。

クライアントからの送信:
 $mtype = $this->msgtype; (クライアント自身のプロセス番号)
 return msg_send($this->hndRx, $mtype, substr($message, 0, $this->msgmaxsize));

サーバーからの返信:
 $mtype = $msgtype;(返信先のプロセス番号)
 return msg_send($this->hndTx, $mtype, substr($message, 0, $this->msgmaxsize));

 メッセージキューで送信できるメッセージはstring型で、長さに上限はないけれど、ジュークボックスシステムでは、コントロール用のキーワード送信にしか使っていない。playとかstopとか、その程度。クライアントからコントロールキーワードが送信され、サーバーがそのキーワードに対応する処理を終えると'ACK'文字列を送信する。クライアントはサーバーからのメッセージ受信が終わるまでウェイトします。サーバーは逆にメッセージがなければスルーします。その制御はmsg_receiveのフラグで指定されます。

クライアント:
 $msgtype = $this->msgtype;
 $flag = MSG_NOERROR;
 $rc = msg_receive($this->hndTx, $msgtype,&$this->rcvid,$this->msgmaxsize,&$message,false,$flag,&$this->opterror);

サーバー:
 $msgtype = 0;
 $flag = MSG_IPC_NOWAIT|MSG_NOERROR;
 $rc = msg_receive($this->hndRx, $msgtype,&$this->rcvid,$this->msgmaxsize,&$message,false,$flag,&$this->opterror);

 クライアント・サーバーの双方で、送信、受信に使うキー(hndTx, hndRx)をたすきがけにすることで、それぞれのキーに対応するメッセージキューは一方向通信のみとして機能します。
 今回はメッセージキューの双方向通信機能をクラスにまとめ、メッセージキーワードの実装までは取り込みませんでした。サーバー側は直接このクラスを利用しますが、クライアントは特定のキーワードを送信する機能をメソッドにしたラッパークラスを利用します。

 共有メモリはサーバーが確保している再生待ちファイルのウェイティングリスト情報を伝達するために使います。クライアントからサーバーへの通信には使われない片方向通信で、制御情報のやり取りにも使われないので特にシビアな排他処理もしていません。
 ただし、安全のため、書き込みができるのはサーバーのみで、クライアントはリードオンリーとしてます。

サーバー側:
 @$this->hndShm = shmop_open($this->shmKey, "n", 0644, $size);
クライアント側:
@$this->hndShm = shmop_open($this->shmKey, "a", 0644, $size);

 共有メモリはサイズが決まっているけど、書き込まれるデータサイズは不定長となります。そのため、共有メモリ先頭10バイトを、書き込みデータの管理領域として、書き込まれたデータサイズの記録領域に割り当てています。データそのものはオフセット10バイトを持って書き込まれることになります。
 データを読み出すときは、まず先頭10バイトを読んでデータサイズを取得したあと、オフセット10バイト以降、データサイズ長分を読みだす動きをします。

書き込み:
(まず、管理領域をクリアします)
 @$rc = shmop_write($this->hndShm, " ", 0);
(データサイズ情報を書き込みます)
 @$rc = shmop_write($this->hndShm, strlen($string), 0);
(データ本体を書き込みます)
 @$rc = shmop_write($this->hndShm, $string, 10);

読み出し:
(データサイズを読み出します)
 @$strSize = shmop_read($this->hndShm, 0, 10);
(整数型にキャストします)
 $numSize = (integer)$strSize;
(オフセット10バイト以降にあるデータ本体を読み出します)
 return shmop_read($this->hndShm, 10, $numSize);

 メッセージングキューも共有メモリも、実装する上では、エラー処理がさらに必要になりますが、ここでは割愛しています。

Copyright (C) 2008-2015 Satosh Saitou. All rights reserved.
戻る
日記::一覧展開
2016.06
卒検突破 (2016.06.26)
急制動 (2016.06.05)
坂道発進 (2016.06.04)
2016.05
スラローム (2016.05.29)
一本橋 (2016.05.28)
半クラ (2016.05.22)
2015.12
2015.11
2015.08
2015.07
2015.06
2015.05
EF50mm F1.8 STM (2015.05.24)
Private Private (2015.05.17)
NTPを整備する (2015.05.02)
2015.04
2015.03
2015.02
潮つ路 (2015.02.22)
未見の星座展 (2015.02.07)
2015.01
PSYCO-PASS劇場版 (2015.01.18)
2014.12
DOMANI/シェル (2014.12.20)
PHPでDMC (2014.12.13)
jouornald (2014.12.07)
2014.11
五木田智央展 (2014.11.08)
2014.10
山口勝弘展 (2014.10.26)
コンタクト (2014.10.18)
ケース加工 (2014.10.11)
山形旅行で (2014.10.04)
2014.09
聖地巡礼 (2014.09.27)
SIAF 2014(3) (2014.09.20)
SIAF 2014(2) (2014.09.14)
SIAF 2014 (2014.09.13)
RaspberryPi B+ (2014.09.06)
2014.08
ヴァロットン (2014.08.09)
GODZILLA(2014) (2014.08.03)
絵画の在りか (2014.08.02)
2014.07
クロニクル1995 (2014.07.26)
SDHCカード集め (2014.07.20)
SDカード再び (2014.07.05)
2014.06
2014.05
駆動系の整備 (2014.05.25)
無限の可能性 (2014.05.24)
PIOON (2014.05.17)
2014.04
大洗 (2014.04.19)
2014.03
唯美主義 (2014.03.09)
写真の境界 (2014.03.02)
2014.02
星を賣る店 (2014.02.15)
日常/オフレコ (2014.02.01)
2014.01
ISCP (2014.01.11)
DOMANI/シェル賞 (2014.01.04)
2013.12
ターナー展 (2013.12.14)
2013.11
反重力 (2013.11.02)
2013.10
木の器 (2013.10.20)
2013.09
ヒステリシス (2013.09.28)
LOVE展 (2013.09.08)
宙色 (2013.09.07)
2013.08
3/4だった (2013.08.17)
福田美蘭展 (2013.08.11)
2013.07
Fedora19 (2013.07.20)
2013.06
Google Cloud Print (2013.06.30)
未来の記憶 (2013.06.16)
梅佳代展 (2013.06.15)
片岡珠子展 (2013.06.09)
椿会展 (2013.06.08)
空想の建物 (2013.06.02)
wiringPi (2013.06.01)
2013.05
2013.04
箱詰め終わる (2013.04.13)
母-娘、姉-妹 (2013.04.06)
2013.03
卒展めぐり (2013.03.30)
恵比寿映像祭 (2013.03.16)
XBeeで接続する (2013.03.10)
Fedora18 (2013.03.09)
Black (2013.03.03)
2013.02
Backupその後 (2013.02.24)
Backup (2013.02.17)
音と光 (2013.02.03)
実験工房 (2013.02.02)
2013.01
いろはにほう (2013.01.26)
燻製を作る (2013.01.19)
2012.12
外装に収める (2012.12.23)
MU (2012.12.22)
スモーク (2012.12.01)
2012.11
Whirl (2012.11.25)
MOTアニュアル (2012.11.18)
2012.10
MPL1151A1 (2012.10.07)
2012.09
(2012.09.16)
夢の光 (2012.09.08)
光のアート (2012.09.01)
2012.08
東京湾大回り (2012.08.26)
2012.07
.hack//VERSUS (2012.07.22)
具体展 (2012.07.21)
国吉康雄展 (2012.07.15)
2012.06
2012.05
DHT11 (2012.05.12)
2012.04
PHPでIPCを行う (2012.04.22)
DHCPを立てる (2012.04.14)
DNSを立てる (2012.04.08)
2012.03
IPv6を追加する (2012.03.17)
MTUを調整する (2012.03.11)
2012.02
ICO再び (2012.02.26)
Viewpoint (2012.02.25)
恵比寿・2 (2012.02.19)
イ・ブル展 (2012.02.18)
恵比寿・1 (2012.02.11)
2012.01
星霜 (2012.01.01)
2011.12
2011.11
美女採取 (2011.11.27)
アサーション (2011.11.20)
日常/ワケあり (2011.11.12)
XB24-BとXB24-ZB (2011.11.06)
2011.10
家電入れ替え (2011.10.23)
2011.09
湿度センサ (2011.09.25)
銀座線ライン (2011.09.17)
竜宮美術旅館 (2011.09.11)
2011.08
しろきもりへ (2011.08.27)
2011.07
免許更新 (2011.07.31)
2011.06
京橋、新橋 (2011.06.26)
シンセシス (2011.06.18)
撤収の準備 (2011.06.04)
2011.05
風穴 (2011.05.15)
PLATFORM (2011.05.14)
2011.04
水・火・大地 (2011.04.17)
2011.03
パーティクル (2011.03.19)
恵比寿映像祭 (2011.03.12)
カナリア (2011.03.06)
2011.02
『ソルト』 (2011.02.19)
豊島美術館 (2011.02.13)
2011.01
藝大先端2011 (2011.01.23)
幽体の知覚 (2011.01.01)
2010.12
PWMで赤外線 (2010.12.26)
2010.11
『水辺にて』 (2010.11.06)
2010.10
アショカの森 (2010.10.30)
補遺の庭 (2010.10.24)
2010.09
シッケテル展 (2010.09.26)
音を鳴らす (2010.09.12)
2010.08
ハーフ (2010.08.21)
発電所美術館 (2010.08.01)
2010.07
2010.06
『未来医師』 (2010.06.13)
会田誠巡り (2010.06.12)
2010.05
桑原漁港 (2010.05.16)
欲望のコード (2010.05.15)
『第9地区』 (2010.05.02)
2010.04
春の海 (2010.04.18)
春の錦帯橋 (2010.04.17)
『機龍警察』 (2010.04.11)
2010.03
虹ヶ浜 (2010.03.28)
菊川湖再び (2010.03.14)
『虐殺器官』 (2010.03.13)
梶取岬 (2010.03.07)
絵画の庭@NMAO (2010.03.06)
2010.02
湯野温泉 (2010.02.06)
2010.01
2009.12
菅野ダム行 (2009.12.20)
2009.11
neoneo展 part2 (2009.11.29)
2009.10
広島ノ顔@HMOCA (2009.10.18)
末武川ダム (2009.10.10)
2009.09
吉宝丸@広島 (2009.09.20)
2009.08
2009.07
下松 (2009.07.12)
T4 (2009.07.05)
2009.06
仙台 (2009.06.07)
蕪島 (2009.06.06)
2009.05
2009.03
2009.02
2009.01
2008.12
神津佐仮説 (2008.12.21)
AVR HTTPサーバ (2008.12.20)
風景るるる (2008.12.14)
2008.11
南志摩・宿浦 (2008.11.22)
志摩あたり (2008.11.01)
2008.10
『剣の名誉』 (2008.10.18)
2008.09
石内都 (2008.09.06)
2008.08
宮島・厳島 (2008.08.30)
精神の呼吸 (2008.08.24)
西国行き (2008.08.23)
ICMP Echo応答 (2008.08.16)
MACフレーム (2008.08.03)
2008.07
小さな世界 (2008.07.26)
早送り (2008.07.20)
屋上庭園・他 (2008.07.13)
夢みる世界 (2008.07.12)
2008.06
古都の残像 (2008.06.01)
2008.05
北陸行 (2008.05.30)
ないまぜ (2008.05.24)
SDカード再び (2008.05.11)
GPSロケーター (2008.05.04)
2008.04
2008.03
音が小さい (2008.03.30)
STILL/MOTION (2008.03.22)
IAMAS2008 (2008.03.16)
80.7MHz/81.3MHz (2008.03.09)
橋頭堡 (2008.03.01)
2008.02
1998.11
作成:2012.03.25
公開:2012.04.22

Valid XHTML 1.1

loading image reserved place