(57)【要約】【課題】メッセージの到達保証を柔軟に実現する通信方法、通信システム、通信装置及びコンピュータプログラムを提供する。【解決手段】パブリッシュ／サブスクライブ型の通信方法において、ブローカであるサーバ装置は、パブリッシャであるクライアント装置から受信したメッセージを、サブスクライバであるクライアント装置へ、多くとも１回到達すべきとする第０次到達保証、少なくとも１回到達すべきとする第１次到達保証、必ず１回到達すべきとする第２次到達保証のいずれで到達させるかの到達保証属性の選択をメッセージ毎に受け付け、自身が処理不可状態となった場合でもメッセージの到達を保証すべきか否かの動作保証属性の選択を受け付け、到達保証属性の選択及び動作保証の選択の組み合わせに応じて、クライアント装置又は他のサーバ装置から受信したメッセージに対する受信処理を切り替える。【選択図】図１
2019176275.tif 000002
【特許請求の範囲】
【請求項１】
パブリッシュ／サブスクライブ型のメッセージを、パブリッシャ又はサブスクライバである複数のクライアント装置との間を仲介する１又は複数のサーバ装置が送受信する通信方法において、
前記サーバ装置は、
パブリッシャであるクライアント装置から受信したメッセージを、サブスクライバであるクライアント装置へ、多くとも１回到達すべきとする第０次到達保証、少なくとも１回到達すべきとする第１次到達保証、必ず１回到達すべきとする第２次到達保証のいずれで到達させるかの到達保証属性の選択をメッセージ毎に受け付け、
自身が処理不可状態となった場合でもメッセージの到達を保証すべきか否かの動作保証属性の選択を受け付け、
到達保証属性の選択及び動作保証の選択の組み合わせに応じて、クライアント装置又は他のサーバ装置から受信したメッセージに対する受信処理を切り替える
通信方法。
【請求項２】
前記サーバ装置は、
前記第１次到達保証が選択されたメッセージの送信先に他のサーバ装置が含まれる場合、該他のサーバ装置から送信される受領確認を受信してから、パブリッシャへ受領確認を返信し、
前記第１次到達保証が選択されたメッセージの送信先に他のサーバ装置が含まれない場合、前記メッセージの送信先への送信処理後に、送信元へ受領確認を返信する
請求項１の通信方法。
【請求項３】
前記サーバ装置は、不揮発性の第１記憶媒体を用い、
前記第１次到達保証が選択されたメッセージの到達を、前記処理不可状態となった場合でも保証すべきと選択された場合、メッセージを送信する前に、該メッセージと、メッセージの配信先、該配信先からの受領確認の有無を含む配信先情報とを前記第１記憶媒体に記憶する
請求項２の通信方法。
【請求項４】
前記サーバ装置は、揮発性の第２記憶媒体を用い、
前記第２次到達保証が選択されたメッセージの送信先に他のサーバ装置が含まれる場合、前記メッセージの受信に使用された第１識別情報と、該他のサーバ装置への送信に使用する第２識別情報との第１の対応関係を前記第２記憶媒体へ記憶し、
前記他のサーバ装置から送信される受領確認を受信してから、送信元へ前記第２記憶媒体へ記憶してある第１識別情報を使用して受領確認を返信し、
前記第１次到達保証が選択されたメッセージの送信先に他のサーバ装置が含まれない場合、前記メッセージの受信に使用された第３識別情報と、該クライアント装置への送信に使用する第４識別情報との第２の対応関係を前記第２記憶媒体へ記憶し、前記メッセージの送信処理後に、前記第２記憶媒体に記憶してある第３識別情報を用いて受領確認を返信する
請求項１の通信方法。
【請求項５】
前記サーバ装置は、不揮発性の第１記憶媒体を用い、
前記第２次到達保証が選択されたメッセージの到達を、前記処理不可状態となった場合でも保証すべきと選択された場合、
前記第１及び第２の対応関係を前記第１記憶媒体に記憶し、
メッセージを送信する前に、該メッセージと、メッセージの配信先、該配信先からの受領確認の有無を含む配信先情報とを前記第１記憶媒体に記憶する
請求項４の通信方法。
【請求項６】
パブリッシュ／サブスクライブ型のメッセージの送受信を仲介する通信装置において、
受信したメッセージを、サブスクライバへ多くとも１回到達すべきとする第０次到達保証、少なくとも１回到達すべきとする第１次到達保証、必ず１回到達すべきとする第２次到達保証のいずれで到達させるかの到達保証属性の選択を受け付ける第１の到達保証属性受付部と、
自身が処理不可状態となった場合でもメッセージの到達を保証すべきか否かの動作保証属性の選択を受け付ける動作保証属性受付部と、
到達保証属性の選択及び動作保証の選択の組み合わせに応じて、受信したメッセージに対する受信処理を切り替える受信処理切替部と
を備える通信装置。
【請求項７】
通信部を備えるコンピュータに、パブリッシュ／サブスクライブ型のメッセージの送受信を実行させるコンピュータプログラムにおいて、
前記コンピュータに、
受信したメッセージを、サブスクライバへ多くとも１回到達すべきとする第０次到達保証、少なくとも１回到達すべきとする第１次到達保証、必ず１回到達すべきとする第２次到達保証のいずれで到達させるかの到達保証属性の選択を受け付ける処理、
自身が処理不可状態となった場合でもメッセージの到達を保証すべきか否かの動作保証属性の選択を受け付ける処理、及び
到達保証属性の選択及び動作保証の選択の組み合わせに応じて、受信したメッセージに対する受信処理を切り替える処理
を実行させるコンピュータプログラム。
【請求項８】
パブリッシュ／サブスクライブ型のメッセージをパブリッシャ又はサブスクライバとして送受信する複数のクライアント装置と、該複数のクライアント装置の間のメッセージの送受信を仲介する１又は複数のサーバ装置とを含む通信システムにおいて、
前記サーバ装置は、
パブリッシャであるクライアント装置から受信したメッセージを、サブスクライバであるクライアント装置へ、多くとも１回到達すべきとする第０次到達保証、少なくとも１回到達すべきとする第１次到達保証、必ず１回到達すべきとする第２次到達保証のいずれで到達させるかの到達保証属性の選択を受け付ける第１の到達保証属性受付部と、
自身が処理不可状態となった場合でもメッセージの到達を保証すべきか否かの動作保証属性の選択を受け付ける動作保証属性受付部と、
到達保証属性の選択及び動作保証の選択の組み合わせに応じて、クライアント装置又は他のサーバ装置から受信したメッセージに対する受信処理を切り替える受信処理切替部と
を含み、
前記クライアント装置は、
通信接続するサーバ装置に対し前記動作保証属性を選択する第１選択部と、
メッセージを送信又は受信する場合に、該メッセージの到達保証属性を選択する第２選択部と
を備える通信システム。
【発明の詳細な説明】
【技術分野】
【０００１】
本開示は、パブリッシュ／サブスクライブ型のメッセージの送受信における到達保証を達成する通信方法、通信システム、通信装置及びコンピュータプログラムに関する。
【背景技術】
【０００２】
簡素な構成で更に通信量が少なくて済むパブリッシュ（Publish ）／サブクライブ（Subscribe ）型（以下、Pub/Sub 型という）のメッセージ送受信システムが、ＩｏＴ（Internet of Things ）システム等の種々の分野で利用されている。Pub/Sub 型のメッセージ送受信では、メッセージ（データ）の送信者であるパブリッシャ（publisher ）と、メッセージの受信者であるサブスクライバ（subscriber）との間のメッセージの送受信をブローカ（broker）と呼ばれるサーバが仲介する。そしてそのメッセージ送受信の仲介には、トピックと呼ばれるメッセージの送信先を区別するための情報が利用される。まずサブスクライバがトピックを指定し、該トピックを送信先とするメッセージを講読する。この講読という処理によりブローカではサブスクライバの識別情報とトピックの識別情報とが対応付けられる。パブリッシャがトピックを指定してメッセージを送信した場合、ブローカはこれを指定されたトピックに対応するサブスクライバへ配信する。これによりパブリッシャは宛先（サブスクライバ）が誰で何人いるかなどを意識することなくメッセージを送信することができる。Pub/Sub 型メッセージ送受信システムは、その適用対象を鑑みれば低帯域のネットワーク上で利用される可能性が高いため、遅延及び損失を考慮する必要がある。
【０００３】
Pub/Sub 型メッセージ送受信システムは、パブリッシャ・ブローカ間、ブローカ・サブスクライバ間及びブローカ・ブローカ間はＴＣＰ／ＩＰセッションを確立させた上でメッセージのやり取りを行なう。そのため、ＴＣＰレイヤにおいては受信確認パケット（ＡＣＫ）を用い、受信側からのＡＣＫの有無によって送信側から再送制御を行なう。ＡＣＫによる再送によって輻輳が生じないよう、中継装置にて制御を行なう技術も提案されている（特許文献１）。このようにPub/Sub 型メッセージ送受信システムは、ＴＣＰ／ＩＰ上でやり取りを行なうため、損失又は遅延により未達のメッセージは、ＴＣＰに基づくセッションが切断しない限りは、ＴＣＰレイヤにおける再送等の技術で保証される。しかしながらセッションが途切れた場合であってもメッセージが確実に相手側に到達することが望まれるケースがある。そこでPub/Sub 型メッセージ送受信システムでは、セッションの切断時の到達保証が規定されている。例えば、MQTT（MQ Telemetry Transport）モデルでは、「At most once」（最高１回、０回又は１回届く）、「At least Once 」（最低１回、１回以上届く）、「Exactly once」（正確に１回、ちょうど１回だけ届く）の３種類の保証を達成するプロトコルが用意されている（非特許文献１）。
【先行技術文献】
【特許文献】
【０００４】
【特許文献１】特開２００６−２８７３３１号公報
【非特許文献】
【０００５】
【非特許文献１】ＩＢＭ株式会社、"4.1. Quality of Service (QoS) レベルおよびフロー"、[online]、MQTT V3.1 プロトコル仕様（日本語）、インターネット＜URL:http://public.dhe.ibm.com/software/dw/jp/websphere/wmq/mqtt31_spec/mqtt-v3r1_ja.pdf＞
【発明の概要】
【発明が解決しようとする課題】
【０００６】
ＩｏＴ関連技術の発展により、ＩｏＴデバイスの数は膨大化し、多様化している。これらのＩｏＴデバイス、更にＩｏＴデバイス以外の通信デバイスをも含むデバイス間でのメッセージを軽量且つ安全にやり取りできるネットワークインフラストラクチャの充実が望まれている。このようなネットワークインフラストラクチャには勿論、Pub/Sub 型メッセージ送受信システムが適合すると考えられる。
【０００７】
Pub/Sub 型メッセージ送受信システムを安全なネットワークインフラストラクチャとして実現するためには、ブローカのインスタンスは複数存在していることが好ましい。更にブローカ自身の障害及び通信障害を考慮すれば、パブリッシャからサブスクライバへメッセージが到達するまでの通信経路は複数パターンが選択可能なネットワークであることが望ましい。この場合、パブリッシャからサブスクライバへ到達するまでにメッセージが経由するブローカの数は、必ずしも１つではなくなる。上述のMQTTモデルにおける到達保証では、パブリッシャ・ブローカ間、あるいはブローカ・サブスクライバ間の１対１のセッションにおける中途切断時のメッセージの到達は保証される。複数のブローカを経由したメッセージについて、経由する通信経路が変化した場合、ブローカがダウンした場合などを考慮した到達保証については考慮されていない。
【０００８】
本発明は斯かる事情を鑑みてなされたものであり、メッセージの到達保証を柔軟に実現する通信方法、通信システム、通信装置及びコンピュータプログラムを提供することを目的とする。
【課題を解決するための手段】
【０００９】
本開示の一態様に係る通信方法は、パブリッシュ／サブスクライブ型のメッセージを、パブリッシャ又はサブスクライバである複数のクライアント装置との間を仲介する１又は複数のサーバ装置が送受信する通信方法において、前記サーバ装置は、パブリッシャであるクライアント装置から受信したメッセージを、サブスクライバであるクライアント装置へ、多くとも１回到達すべきとする第０次到達保証、少なくとも１回到達すべきとする第１次到達保証、必ず１回到達すべきとする第２次到達保証のいずれで到達させるかの到達保証属性の選択をメッセージ毎に受け付け、自身が処理不可状態となった場合でもメッセージの到達を保証すべきか否かの動作保証属性の選択を受け付け、到達保証属性の選択及び動作保証の選択の組み合わせに応じて、クライアント装置又は他のサーバ装置から受信したメッセージに対する受信処理を切り替える。
【００１０】
本開示の一態様に係る通信装置は、パブリッシュ／サブスクライブ型のメッセージの送受信を仲介するサーバ装置において、受信したメッセージを、サブスクライバへ多くとも１回到達すべきとする第０次到達保証、少なくとも１回到達すべきとする第１次到達保証、必ず１回到達すべきとする第２次到達保証のいずれで到達させるかの到達保証属性の選択を受け付ける第１の到達保証属性受付部と、自身が処理不可状態となった場合でもメッセージの到達を保証すべきか否かの動作保証属性の選択を受け付ける動作保証属性受付部と、到達保証属性の選択及び動作保証の選択の組み合わせに応じて、受信したメッセージに対する受信処理を切り替える受信処理切替部とを備える。
【００１１】
本開示の一態様に係るコンピュータプログラムは、通信部を備えるコンピュータに、パブリッシュ／サブスクライブ型のメッセージの送受信を実行させるコンピュータプログラムにおいて、前記コンピュータに、受信したメッセージを、サブスクライバへ多くとも１回到達すべきとする第０次到達保証、少なくとも１回到達すべきとする第１次到達保証、必ず１回到達すべきとする第２次到達保証のいずれで到達させるかの到達保証属性の選択を受け付ける処理、自身が処理不可状態となった場合でもメッセージの到達を保証すべきか否かの動作保証属性の選択を受け付ける処理、及び到達保証属性の選択及び動作保証の選択の組み合わせに応じて、受信したメッセージに対する受信処理を切り替える処理を実行させる。
【００１２】
本開示の一態様に係る通信システムは、パブリッシュ／サブスクライブ型のメッセージをパブリッシャ又はサブスクライバとして送受信する複数のクライアント装置と、該複数のクライアント装置の間のメッセージの送受信を仲介する１又は複数のサーバ装置とを含む通信システムにおいて、前記サーバ装置は、パブリッシャであるクライアント装置から受信したメッセージを、サブスクライバであるクライアント装置へ、多くとも１回到達すべきとする第０次到達保証、少なくとも１回到達すべきとする第１次到達保証、必ず１回到達すべきとする第２次到達保証のいずれで到達させるかの到達保証属性の選択を受け付ける第１の到達保証属性受付部と、自身が処理不可状態となった場合でもメッセージの到達を保証すべきか否かの動作保証属性の選択を受け付ける動作保証属性受付部と、到達保証属性の選択及び動作保証の選択の組み合わせに応じて、クライアント装置又は他のサーバ装置から受信したメッセージに対する受信処理を切り替える受信処理切替部とを含み、前記クライアント装置は、通信接続するサーバ装置に対し前記動作保証属性を選択する第１選択部と、メッセージを送信又は受信する場合に、該メッセージの到達保証属性を選択する第２選択部とを備える。
【発明の効果】
【００１３】
本開示によれば、多様な構成でもセッション毎のメッセージの到達保証のみならず、パブリッシャからサブスクライバまでのメッセージの到達保証を、実現される。
【図面の簡単な説明】
【００１４】
【図１】本実施の形態における通信システムの概要図である。
【図２】通信システムを構成する各装置のハードウェア構成を示すブロック図である。
【図３】MQTTモデルにおける到達保証を示すシーケンス図である。
【図４】keep接続が選択された場合のサーバ装置の処理手順の一例を示すフローチャートである。
【図５】keep接続によるサブスクライブ状態の維持を示す説明図である。
【図６】装置間の接続例を示す図である。
【図７】図６の接続状態にて装置間で送信されるメッセージの具体例を示す。
【図８】図６に対する切断状態を示す図である。
【図９】図８に示した切断状態でパブリッシャからメッセージが送信された場合の処理の一例を示す図である。
【図１０】図８に示した切断状態でパブリッシャからメッセージが送信された場合の処理の一例を示す図である。
【図１１】再接続後の処理を示す。
【図１２】QoS =1の場合の処理例を示す。
【図１３】QoS =2の場合の処理例を示す。
【図１４】QoS =2の場合の処理例を示す。
【図１５】サーバ装置がセッション切断を検知した際に実行する処理手順の一例を示すフローチャートである。
【図１６】クライアント装置がサーバ装置と切断された状態を示す図である。
【図１７】図１６の切断状態から復帰した場合の処理手順を示す図である。
【図１８】クライアント装置がサーバ装置と切断された他の状態の例を示す図である。
【図１９】図１８の切断状態から復帰した場合の処理手順を示す図である。
【図２０】QoS =1におけるブローカであるサーバ装置によるメッセージ配信の処理手順の一例を示すフローチャートである。
【図２１】送信順序を示す説明図である。
【図２２】送信順序の他の例を示す説明図である。
【図２３】サーバ装置及びクライアント装置の接続構成を示す図である。
【図２４】ブローカ間が切断された場合のサーバ装置における処理手順の一例を示すフローチャートである。
【図２５】図２３に示した接続構成におけるブローカ間のセッションが切断された場合の処理の例を示す説明図である。
【図２６】図２３に示した接続構成におけるブローカ間のセッションが切断された場合の処理の例を示す説明図である。
【図２７】図２３に示した接続構成におけるブローカ間のセッションが切断された場合の処理の例を示す説明図である。
【図２８】ブローカ間切断中のメッセージ処理手順の一例を示すフローチャートである。
【図２９】ブローカダウンを保証するサーバ装置における送信手順の一例を示すフローチャートである。
【図３０】QoS =1でブローカダウンを保証する際の処理を示す図である。
【図３１】QoS =1でブローカダウンを保証する際の処理を示す図である。
【図３２】QoS =1でブローカダウンを保証する際の処理を示す図である。
【図３３】QoS =1でブローカダウンを保証する際の処理を示す図である。
【図３４】サーバ装置の起動時の処理手順の一例を示すフローチャートである。
【図３５】ブローカであるサーバ装置（b2）がダウンした場合の処理を示す図である。
【図３６】ブローカであるサーバ装置（b2）がダウンした場合の処理を示す図である。
【図３７】図３６に示した状態の後、サーバ装置（b2）が起動した後に行なわれる処理の例を示す図である。
【図３８】QoS =2におけるパケットＩＤ対応情報の説明図である。
【図３９】パケットＩＤ対応情報を用いたメッセージの処理手順の一例を示すフローチャートである。
【図４０】パケットＩＤ対応情報の内容例を示す図である。
【図４１】パケットＩＤ対応情報の内容例を示す図である。
【図４２】パケットＩＤ対応情報の内容例を示す図である。
【図４３】サーバ装置（b2）におけるサブスクライバとのセッション切断検知時の処理手順の一例を示すフローチャートである。
【図４４】ブローカ間のセッションが切断された場合の処理の例を示す説明図である。
【図４５】ブローカ間のセッションが切断された場合の処理の例を示す説明図である。
【図４６】ブローカ間のセッションが切断された場合の処理の例を示す説明図である。
【図４７】QoS =2におけるブローカ間のセッションの再確立後のメッセージ送信処理の一例を示すフローチャートである。
【図４８】QoS =2でブローカダウンを保証する際の処理を示す図である。
【発明を実施するための形態】
【００１５】
以下、本開示の通信方法及び通信システムについてその実施の形態を示す図面に基づいて具体的に説明する。
【００１６】
図１は、本実施の形態における通信システム１００の概要図である。通信システム１００は、複数のサーバ装置１と、複数のクライアント装置２とを含む。サーバ装置１及びクライアント装置２は夫々、ネットワークＮを介して通信することが可能である。特に複数のサーバ装置１は相互に通信接続することが可能である。このときネットワークＮに参加するサーバ装置１の数は例えば数十台である。クライアント装置２は複数のサーバ装置１の内のいずれかと通信接続（セッションを確立）することが可能である。複数のサーバ装置１はいずれも、共通するデータベース３にアクセスが可能である。データベース３はサーバ装置１内部又はサーバ装置１外部に通信媒体を介して接続可能に設けられている。複数のデータベース３は内容が同期するようにしてあり、サーバ装置１は、いずれのデータベース３から情報を取得してもよい。
【００１７】
複数のサーバ装置１は夫々サーバコンピュータであり、Pub/Sub 型メッセージ送受信システムにおけるブローカとして機能する。複数のクライアント装置２は所謂ＩｏＴ機器であって、無線による通信部と、センサ又はスイッチとを含む機器である。クライアント装置２はスマートフォン等の通信端末機器であってもよい。クライアント装置２は夫々、パブリッシャ又はサブスクライバのいずれか一方若しくは両方として機能する。例えばスマートフォンであるクライアント装置２によって遠隔からスイッチ機器のクライアント装置２へ制御内容を送信して制御したり、センサ機器であるクライアント装置２からスマートフォンであるクライアント装置２へ測定結果を送信したりする。前者のパターンではスマートフォンであるクライアント装置２がパブリッシャとして、スイッチ機器であるクライアント装置２がサブスクライバとして機能し、後者のパターンではセンサ機器であるクライアント装置２がパブリッシャとして機能し、スマートフォンであるクライアント装置２がサブスクライバとして機能する。
【００１８】
通信システム１００では、複数のサーバ装置１群の利用をクライアント装置２に許可することにより、クライアント装置２から他のクライアント装置２をネットワークＮ経由で制御したり、多数のクライアント装置２から情報を収集することを可能としたりするサービスを実現することが可能である。ここで、スマートフォンであるクライアント装置２からスイッチ機器であるクライアント装置２を制御するに際し、これらの間を２つのサーバ装置１がブローカとして仲介する場合を考える。クライアント装置２とサーバ装置１との間、又は２つのサーバ装置１間のセッションが切断されるか、サーバ装置１が動作を停止（ダウン）したことで、制御情報を含むメッセージが損失すると、スイッチ制御が意図されたものとは異なる内容となる可能性がある。本実施の形態における通信システム１００では、セッションを確立するサーバ装置１とクライアント装置２との間におけるメッセージの到達保証のみならず、複数のサーバ装置１を経由するメッセージのやり取りにおいてもサーバ装置１のダウンさえも考慮した到達保証を実現する。
【００１９】
図２は、通信システム１００を構成する各装置のハードウェア構成を示すブロック図である。サーバ装置１はサーバコンピュータを用いる。サーバ装置１は、ハードウェア的に１台のサーバコンピュータに対して、論理的に１つの装置として実現されるとは限らない。大抵の場合、１台のサーバコンピュータにて論理的に複数が動作する仮想マシンにより実現される。後述のクライアント装置２及びデータベース３についても同様である。ただし説明を簡易とするため、以下の説明では、サーバ装置１及びクライアント装置２は物理的に１つのコンピュータを用い、データベース３は１つの記憶装置を用いることとして説明する。
【００２０】
サーバ装置１は夫々、制御部１０、第１記憶部１１、第２記憶部１２、一時記憶部１３及び通信部１４を備える。制御部１０はＣＰＵ（Central Processing Unit ）、ＧＰＵ（Graphics Processing Unit）等のプロセッサを用い、第１記憶部１１に記憶されているサーバプログラム１Ｐに基づいた各処理を実行し、汎用サーバコンピュータをPub/Sub 型メッセージ送受信システムにおけるブローカとして機能させる。なお本実施の形態のサーバ装置１は基本的には、MQTTモデルのブローカに準拠した動作を行なう。一時記憶部１３はＤＲＡＭ（Dynamic Random Access Memory）等の揮発性メモリを用いて制御部１０の処理により生成される情報を一時的に記憶する。
【００２１】
第１記憶部１１は、ハードディスク又はフラッシュメモリ等の不揮発性メモリを用いる。第１記憶部１１は、サーバプログラム１Ｐのほか、制御部１０が処理の際に参照する情報を記憶する。
【００２２】
第２記憶部１２は、第１記憶部１１同様にサーバ装置１が内蔵する不揮発性メモリの一部を用いるか、又は、外部の記憶装置を用いる。第２記憶部１２は、後述する通信処理においてサーバ装置１間で共有されるべきデータベース３として利用される。データベース３の内容については後述にて詳細を説明する。
【００２３】
通信部１４は、ネットワークカード又は無線通信デバイスを用い、ネットワークＮへの通信接続を実現する。通信部１４はＴＣＰ／ＩＰに準じた通信を行なうが、これに代替するプロトコルであっても構わない。サーバ装置１は通信部１４によりネットワークＮを介した通信接続を実現し、他のサーバ装置１との間で、１対１でセッションを確立し、図１に示したようなメッシュ状のネットワークを構築する。
【００２４】
ネットワークＮは、所謂インターネットである公衆網、通信キャリアネットワーク、及びＩｏＴサービスを実現する事業者の事業者ネットワーク、それらへの接続拠点である基地局、アクセスポイント等を含む総称である。なおサーバ装置１はネットワークＮの事業者ネットワークからネットワークＮへ接続し、クライアント装置２は公衆網、通信キャリアネットワークからネットワークＮに接続している。
【００２５】
データベース３は上述したようにサーバ装置１の第２記憶部１２を用いて実現されるか、又はサーバ装置１からは独立した外部記憶装置（ハードディスク及び記憶処理部）を用いてネットワークＮに接続されている構成としてもよい。
【００２６】
クライアント装置２は種々のコンピュータによって実現されるが、少なくとも制御部２０、記憶部２１、及び通信部２３を備える。制御部２０は、ＣＰＵ、マイクロプロセッサ等及びクロックを用い、記憶部２１に記憶してある端末用プログラム２Ｐに基づいた各処理により、汎用コンピュータをPub/Sub 型メッセージ送受信システムにおけるパブリッシャ又はブローカとして機能させる
【００２７】
記憶部２１はフラッシュメモリ等不揮発性メモリを用いる。記憶部２１にはPub/Sub 型メッセージ送受信を実現するための端末用プログラム２Ｐが記憶されているほか、制御部２０が処理の際に参照する情報を記憶する。
【００２８】
通信部２２は、ネットワークカード又は無線通信デバイスを用い、ネットワークＮへの通信接続を実現する。
【００２９】
通信システム１００におけるメッセージの到達保証を実現する具体的方法について、以下フローチャート及び説明図を参照しながら、下記のように段階的に説明する。
１．装置間の通信における前提
（０）装置間のセッション
（１）QoS （到達保証）の基本
（２）keep接続
（３）ブローカ間のセッション
２．複数の保証レベル
（１）QoS =0（ゼロ）
（２）QoS =1、ただしブローカがダウンした場合は保証しない
（３）QoS =1、ブローカがダウンした場合も保証する
（４）QoS =2、ただしブローカがダウンした場合は保証しない
（５）QoS =2、ブローカがダウンした場合も保証する
【００３０】
［１．装置間の通信における前提］
（０）セッション
クライアント装置２とサーバ装置１、サーバ装置１とサーバ装置１の間は基本的に、互いにセッションを確立し、そのセッション内でメッセージをやり取りする。サーバ装置１は、複数のクライアント装置２及びサーバ装置１とセッションを確立することができ、そのセッション毎に通信相手を識別している（誰とのセッションかを識別する）。
【００３１】
（１）QoS （到達保証）の基本
複数のサーバ装置１は、上述したように基本的にMQTTモデルにおけるブローカに準拠している。したがってサーバ装置１は、クライアント装置２及び他のサーバ装置１との間のメッセージのやり取りについて、MQTTモデルの到達保証をベースに処理を実行する。図３は、MQTTモデルにおける到達保証を示すシーケンス図である。MQTTモデルでは、送信者からpublish メッセージとしてデータが送信され、このpublish メッセージは、トピック（[topic] ）、送信対象のデータ（ペイロード）（[data/payload]）、及び到達保証レベル（[qos]）を含む。到達保証レベルによっては、パケットを識別するパケットＩＤ（[packet_id]）を含む。なお、ここ及び以下の説明にて［］内はフィールド名の例を表わし、各々には適切な数値又は論理値が入り使用される。図３のシーケンス図では、メッセージの送信者と受信者との間のメッセージについての取決めが、QoS レベルが０（ゼロ），１，２である場合について夫々示されている。送信者は、メッセージを送信する（publish ）に際し、QoS レベル（qos ）を０，１，２のいずれかから指定することができる。
【００３２】
図３Ａで示すように、パブリッシャである送信者があるトピック（topic ）についてデータ（data）をpublish メッセージとして送信する際に、QoS レベルとして「０（ゼロ）」を指定した場合、そのメッセージに対して受信者は、受信処理以外の処理は行なわない。これにより送信者側からは、メッセージが到達したか否かを確認することはできず、到達していない場合にもその状況を知り得ない。ただ、最新のデータをその都度送信する場合には、QoS ＝０で十分に足りる。
【００３３】
図３Ｂで示すように、パブリッシャである送信者があるトピックについてデータを送信する際にQoS として「１」を指定した場合（qos =1）、送信するパケットのパケットＩＤ（packet_id）を送信者と受信者との間のセッション内で採番して指定して送信する（図３Ｂではpacket_id=0x10）。この場合受信者は、パケットＩＤを指定してpubackというメッセージを返し、送信者側はこのpubackメッセージを受信するまで、送信したデータをパケットＩＤと共に保持（一時記憶）する。送信者があるトピックについてデータを送信し、その送信に対してpubackメッセージを受信する前に受信者との間でセッションが切断された場合、送信者は受信者とのセッションを再確立した後に、一時記憶しているpublish メッセージを、記憶しているパケットＩＤを指定して再送する。これにより、送信者は、受信者側でデータを受信した事実を知ることができ、受信者は、セッションの切断があったとしても必ずデータを受信することができる。ただしこの場合、データが受信者に到達してからセッションが切断されたか、到達する前に切断されたかを区別することができず、データを受信してからセッションが切断された場合には、同一のデータを複数回受信することになる。
【００３４】
図３Ｃで示すように、パブリッシャである送信者があるトピックについてpublish メッセージを送信する際に、QoS として「２」を指定した場合、「１」を指定した際と同様に、送信するパケットのパケットＩＤを採番して使用して送信する（図３Ｃではpacket_id=0x11）。この場合受信者は、パケットＩＤを指定してpubrecメッセージを返し、同一のパケットＩＤを指定して送信されたデータについては以後、破棄する。したがってデータの再送を受けたとしてもこれを破棄してデータの受信を１回のみとすることができる。送信者はこのpubrecメッセージを受信するまで、送信したデータをパケットＩＤと共に保持し、pubrecメッセージを受信した場合には一時記憶していたデータを破棄する。破棄したデータと共に記憶していたパケットＩＤは新たなデータの送信に使用できるので、送信者はこれを宣言するpubrelメッセージをパケットＩＤと共に送信する。受信者はこのpubrelメッセージを受信したことを示すpubcomp メッセージを送信し、これによりQoS レベルが「２」のメッセージの送受信は完了する。QoS =2の場合もセッションが切断された場合、送信者は受信者とのセッションを再確立した後に、pubrecメッセージを未受信であればpublish メッセージを再送し、pubcomp メッセージを未受信であればpubrelメッセージを再送する。
【００３５】
なお図３Ｂ及び図３Ｃで示したメッセージのやり取りの中で、セッションが切断されるケースでは、受信者側では、送信者側からpublish メッセージ又はpubrelメッセージが送信された場合にこれらのメッセージが再送か否かに拘わらず、これに応答してpubrecメッセージ又はpubcomp メッセージを応答として送信する。受信者側では、publish メッセージ又はpubrelメッセージを受信していないのにpubrecメッセージ又はpubcomp メッセージを再送することはない。
【００３６】
なお図３Ａから図３Ｃに示したMQTTにおける到達保証は、送信者と受信者という２つの装置間でのメッセージの到達保証の規定である。したがって、同一のトピックの同一のデータについてパブリッシャから接続対象のブローカまでのメッセージがQoS レベルとして「２」を指定して送信されたとしても、サブスクライバまでの到達がQoS レベル「２」で保証されるわけではない。これに対し本実施の形態における通信システム１００では、MQTTにおける到達保証を利用しつつ、その到達保証の対象を、直接的にセッションを確立する２つの装置間のみならず、サブスクライバへ到達するまでの経路で最適化する。更には、セッションの切断のみならずブローカがダウンして一時記憶が破棄される状態となった場合も含めてメッセージの到達を保証する。これらの到達保証の実現については［２．］以降で説明する。
【００３７】
（２）keep接続
通信システム１００では、サブスクライバであるクライアント装置２からサーバ装置１へのセッション確立の際には、「keep」というオプションを選択できるようにしてある。keep接続は、MQTTモデルにおける「CleanSesson 」というオプションで「false 」を選択してセッションを確立することに対応する。クライアント装置２はサーバ装置１へ通信接続をリクエストする際に「keep」オプションをtrueに指定しておけば、サーバ装置１との間のセッションが切断されたとしても、切断されている間にサーバ装置１へ到達したメッセージを後に受信することができる。
【００３８】
keep接続を実現するための処理について説明しておく。図４は、keep接続が選択された場合のサーバ装置１の処理手順の一例を示すフローチャートである。サーバ装置１の制御部１０は、サーバプログラム１Ｐに基づき、クライアント装置２からの通信接続のリクエストを検知すると以下の処理を実行する。
【００３９】
制御部１０は、通信接続してきたクライアント装置２のクライアントＩＤ（user_id）及び通信接続してきたクライアント装置２からの接続のオプション（「keep」オプション（keep＝true又はfalse ））を一時記憶する（ステップＳ１）。
【００４０】
制御部１０はまず、クライアントＩＤを基に第２記憶部１２のデータベースに記憶してあるセッション情報（後述のステップＳ８）を参照し（ステップＳ２）、接続してきたクライアント装置２に対応するセッション情報が新規であるか否かを判断する（ステップＳ３）。セッション情報がデータベースに存在せず、新規であると判断された場合（Ｓ３：ＹＥＳ）、制御部１０はクライアントＩＤに対応付けて接続中であることを示す状態情報を新規に一時記憶部１３に記憶し（ステップＳ４）、これにより新規セッションが開始される。
【００４１】
次に制御部１０は、セッションを確立しているクライアント装置２からサブスクライブ対象とするトピックの指定を到達保証レベル（QoS ）の指定と共に受信すると（ステップＳ５）、指定されたトピック及び指定されたQoS をクライアントＩＤに対応付けて一時記憶部１３に記憶する（ステップＳ６）。
【００４２】
制御部１０は、対象のクライアント装置２からの通信接続の「keep」オプションがtrueであるか否かを判断し（ステップＳ７）、trueであると判断された場合（Ｓ７：ＹＥＳ）、クライアントＩＤとに対応付けてステップＳ５にて対象とされた指定トピック（文字列）及びQoS をセッション情報として第２記憶部１２のデータベース３（「keep_sub」テーブル）に記憶する（ステップＳ８）。ステップＳ８において制御部１０は、記憶するセッション情報が既に記憶されている情報と同一である場合、そのままとしておけばよい。
【００４３】
その後制御部１０は、指定トピックに対してパブリッシャからデータが送信される都度、このデータをサブスクライバであるクライアント装置２へ配信する処理を実行し（ステップＳ９）、該クライアント装置２とのセッションが切断されたか否かを判断する（ステップＳ１０）。切断されていないと判断された場合（Ｓ１０：ＮＯ）、制御部１０は処理をステップＳ９へ戻し、指定トピックについての配信処理を続行する。
【００４４】
切断されたと判断された場合（Ｓ１０：ＹＥＳ）、対応するクライアントＩＤの状態情報を消去して（ステップＳ１１）、指定トピックの配信先をデータベースへと変更し（ステップＳ１２）、処理を終了する。以後制御部１０は、指定トピックについてのメッセージに含まれるデータ（ペイロード）については、トピックの識別情報に対応付けてデータベース３（「store 」テーブル及び「store_target」テーブル）に記憶する。
【００４５】
通信接続の「keep」オプションがtrueでない（即ちfalse である）と判断された場合（Ｓ７：ＮＯ）、制御部１０は、指定トピックに対してパブリッシャからデータが送信される都度に、これをサブスクライバであるクライアント装置２へ配信する処理を実行する（ステップＳ１３）。そして制御部１０は、クライアント装置２とのセッションが切断されたか否かを判断する（ステップＳ１４）。切断されていないと判断された場合（Ｓ１４：ＮＯ）、制御部１０は処理をステップＳ１３へ戻し、トピックに対する配信処理を続行する。切断されたと判断された場合（Ｓ１４：ＹＥＳ）、対応するクライアントＩＤの状態情報を消去して（ステップＳ１５）、処理を終了する。この場合、第２記憶部１２のデータベースには情報の記憶がされない。
【００４６】
ステップＳ３にてセッション情報が存在し、既存であると判断された場合（Ｓ３：ＮＯ）、対象のクライアント装置２は再接続であるから、制御部１０はデータベースに同一のクライアントＩＤに対応付けて記憶されている指定トピックを読み出して状態情報を復元する（ステップＳ１６）。
【００４７】
そして制御部１０は、再接続時の「keep」オプションがtrueであるか否かを判断する（ステップＳ１７）。trueであると判断された場合（Ｓ１７：ＹＥＳ）、制御部１０は、指定トピックについて第２記憶部１２のデータベースに記憶されているデータ（ペイロード）を取り出して再接続してきたクライアント装置２へ配信する（ステップＳ１８）。制御部１０は、処理をステップＳ９へ進める。
【００４８】
ステップＳ１７にてtrueでない（false ）と判断された場合（Ｓ１７：ＮＯ）、第２記憶部１２のデータベースに記憶されているクライアントＩＤと指定トピックの対応であるセッション情報を消去し（ステップＳ１９）、処理をステップＳ１３へ進める。
【００４９】
図５は、keep接続によるサブスクライブ状態の維持を示す説明図である。図５は、サブスクライバであるクライアント装置２からブローカのサーバ装置１への接続、切断等のイベントを図の上部から下部へ時系列に示し、各イベントによるサブスクライブ状態の変化を示している。「keep」オプションをtrueに指定して接続した場合には、その後に切断されたとしてもその期間に指定トピックに対してパブリッシャから送信されたメッセージについて、再接続後に配信を受けることができ、サブスクライバであるクライアント装置２は漏れなくメッセージを受信することができる。
【００５０】
図６から図１４を参照して、keep接続によるメッセージの配信処理実現の具体的方法をについて説明する。図６は、装置間の接続例を示す図である。識別情報「p1」のクライアント装置２（以下、サーバ装置１又はクライアント装置２（識別情報）と記載する）がパブリッシャとしてサーバ装置１（b1）（ブローカ）に通信接続し（セッションＡ）、クライアント装置２（s2）が、サブスクライバとしてサーバ装置１（b1）に通信接続（セッションＢ）する例を示している。サブスクライバであるクライアント装置２（s1）は、サーバ装置１へkeep接続（「keep」オプションをtrueに指定して通信接続）している。クライアント装置２（s1）からトピック「t1」が指定されると、サーバ装置１（b1）は、サブスクライバ毎に、その識別情報（[user_id] ）と対応付けて、指定トピック（[topic] ）及び指定されたQoS を含むセッション情報をデータベース３（「keep_sub」テーブル）に記憶する。図６の例では、サブスクライバであるクライアント装置２（s1）について（user_id=s1）、指定トピック（topic=t1）及び指定されたQoS （[qos] ）を記憶している。
【００５１】
また図６では、クライアント装置２（s2）もサブスクライバとしてサーバ装置１（b1）に通信接続している（セッションＣ）。クライアント装置２（s2）は、サーバ装置１（b1）に通信接続する際に「keep」オプションをfalse （非keep）として通信接続しているので、データベース３（「keep_sub」テーブル）には対応するセッション情報が記憶されない。クライアント装置２（s2）がクライアント装置２（s1）と同様にトピック「t1」を指定した場合、以後、トピック「t1」についてパブリッシャであるクライアント装置２（p1）からpublish メッセージが送信される都度、ブローカであるサーバ装置１（b1）からはクライアント装置２（s1, s2）へ指定されたQoS でpublish メッセージが送信される。
【００５２】
図７は、図６の接続状態にて装置間で送信されるメッセージの具体例を示す。パブリッシャであるクライアント装置２（p1）は例えば、「t1」というトピックについて「a 」というペイロード（data/payload）を含むpublish メッセージを、その送信の都度、QoS （１又は２）を指定して送信する。図７中[qos] にてQoS の指定値が含まれることを示している。このpublish メッセージには、セッション毎に起点側で採番されるパケットＩＤ（packet_id=0x100 ）が付与されている。図７の図に示す状態ではクライアント装置２（s1）の状態情報はonlineであってトピック「t1」をサブクライブしている。サーバ装置１（b1）は、到達したメッセージのトピック「t1」を参照し、該トピックを指定しているサブスクライバであるクライアント装置２（s1）へ向けてペイロード（data/payload=a）を含むpublish メッセージを送信する。サーバ装置１（b1）からクライアント装置（s1）へのpublish メッセージのQoS は、クライアント装置２（s1）がサーバ装置１（b1）へサブスクライブ対象のトピックを指定する際に指定してセッション情報として記憶しているQoS と、パブリッシャから送信される際に指定されたQoS との内の小さい方に調停される。またサーバ装置１（b1）から送信されるメッセージのパケットに付与されているパケットＩＤ（packet_id=0x101 ）は、送信者であるサーバ装置１（b1）によって採番されている。同様にしてクライアント装置２（s2）へもペイロード（data/payload=a）を含むpublish メッセージが送信されている（パケットＩＤ（packet_id=0x103）は別途採番されている）。
【００５３】
図８は、図６に対する切断状態を示す図である。図８は、図６に示した接続状態から、クライアント装置２（s1, s2）とサーバ装置１との間のセッションＢ，Ｃが切断された状態となったことを示している。サーバ装置１では、クライアント装置２（s1）とのセッション切断を検知し、対応するセッション情報（s1）に対応するトピックについて配信先をデータベース３とすることを一時記憶している。一方でサーバ装置１は、クライアント装置２（s2）とのセッション切断を検知しても、このセッションは非keepであったので対応する状態情報（s2）を一時記憶していない。
【００５４】
図９及び図１０は、図８に示した切断状態でパブリッシャからメッセージが送信された場合の処理の一例を示す。クライアント装置２（p1）が図７同様に、「t1」というトピックについて「a 」というペイロードを含むpublish メッセージを、QoS （１又は２）を指定して送信する。図中[qos] にてQoS の指定値がメッセージに含まれることを示している。この場合、ブローカであるサーバ装置１（b1）は、識別情報「s1」のセッション情報に対応するトピック「t1」のメッセージについては配信先をデータベース３とすることを記憶しているから、データベース３（「store 」テーブル）に、トピック毎にメッセージを記憶する。このメッセージは保存メッセージとして記憶される。保存メッセージは例えば、メッセージ各々を識別する識別子（[store_id]）、トピック（[topic] ）、メッセージの内容（[data/payload]）を含む。保存メッセージは、ブローカでの受信時刻（[TS]）を含んでもよい。図９の例では、「123 」の識別子（store_id=123）が付されたトピック（topic=t1）について「a 」（data/payload=a）という内容の保存メッセージが記憶されている。
【００５５】
図１０に示すようにサーバ装置１（b1）は続けて、データベース３に記憶した保存メッセージ（「store 」）の配信先の情報（配信先情報）を、配信先の装置の識別情報毎に更にデータベース３（「store_target」テーブル）に記憶する。一回のpublish の実行に対し記憶される保存メッセージ（「store 」テーブル）は１つであるが、配信先情報（「store_target」テーブル）は、保存メッセージの配信先の数分だけ存在することとなる。配信先情報は、配信先の識別情報（[user_id] ）、送信した際のパケットＩＤ（[packet_id] ）、メッセージの識別子（[store_id]）、送信されたか否かを示すフラグ（[already_sent]）、及び送信する際のQoS （[qos] ）を含む。図１０の例であれば、保存メッセージ（id=123）が、クライアント装置２（user_id=s1）向けに未送信である（already_sent=false）ことを示す配信先情報が記憶されている。またメッセージのパケットＩＤが対応付けて記憶される。図１０の例では、publish メッセージの受信時に配信先とのセッションＢは切断していることが分かっており、この場合パケットＩＤはNULL（MQTTで利用できる範囲（0x0001-0xffff）外を設定）に設定されている。そして配信先に対応付けて、QoS が記憶されている。このQoS は配信先のサブスクライバからサブスクライブ対象のトピックを指定する際に指定したQoS と、パブリッシャからメッセージが送信される際に指定されたQoS とで数値が小さい方のQoS とする。
【００５６】
そしてサーバ装置１は、パブリッシャのクライアント装置２へ向けて、publish メッセージに対するpubackメッセージ（QoS =1）又はpubrecメッセージ（QoS =2）を返す。
【００５７】
図１１は、再接続後の処理を示す。クライアント装置２（s1）がサーバ装置１（他のサーバ装置１でもよい）と再び通信接続すると（セッションＢ）、データベース３に記憶してあるセッション情報（「keep_sub」テーブル）から、サーバ装置１側で指定トピック等のセッション情報を読み出して状態情報を復元する。そしてサーバ装置１は、データベース３に記憶されている配信先情報（「store_target」テーブル）からクライアント装置２（user_id=s1）向けの未送信メッセージ（already_sent=false）を検索する。クライアント装置２（s1）への「123 」という識別子が付された保存メッセージが未送信であることが参照される。サーバ装置１はデータベース３（「store 」テーブル）から識別子「123 」である保存メッセージのペイロード（data/payload=a）を読み出し、サブクライバであるクライアント装置２（s1）へpublish メッセージとして送信する。このとき、クライアント装置（s1）向けの配信先情報では、予め切断していた状態であってパケットＩＤが採番されていなかった（NULLである）ので、改めてパケットＩＤ（packet_id=0x102 ）が採番されている。配信先情報のパケットＩＤも採番されたパケットＩＤで更新される。クライアント装置２（s2）からの再接続については、前回の接続が非keepであったので状態情報は復元されることなしに、新たなセッション（セッションＣ）を確立する。また、クライアント装置２（s2）からサブスクライブするトピックを指定する処理が行なわれない限り、サーバ装置１は、クライアント装置２（s2）の指定トピックを認識しない。
【００５８】
サーバ装置１（b1）は、データベース３に記憶されていた配信先情報（「store_target」）を、配信先へ送信できたことによって削除する。具体的には例えば、配信先からpubackメッセージを受信し、配信先での受信が確実に確認できた場合に配信先情報を削除する。記憶の削除タイミングはこれに限らず、適切に設計されるとよい。識別子「123 」の保存メッセージは、識別情報「s1」の配信先情報のみの配信先が対応していたので、送信済みとなる。サーバ装置１（b1）はデータベース３（「store 」テーブル）から保存メッセージを消去する。ただし指定されているQoS によって処理が異なる。図１２は、QoS =1の場合の処理例を示す。データベース３の配信先情報（「store_target」テーブル）におけるクライアント装置２（s1）向けのメッセージについてQoS が「１（At least Once ）」である場合、サーバ装置１（b1）は、図１１に示したメッセージ（publish ）の送信後、クライアント装置２（s1）からpubackメッセージが返信されたことを確認すると、データベース３（「store_target」テーブル及び「store 」テーブル）から「s1」向けの「123 」に係るレコードを消去する。
【００５９】
図１３及び図１４は、QoS =2の場合の処理例を示す。データベース３に記憶されている配信先情報（「store_target」テーブル）に記憶してある情報が、「s1」向けのメッセージについてQoS が「２（Exactly once）」である場合の例である。サーバ装置１は、図１１に示したpublish メッセージの送信後、クライアント装置２からpubrecメッセージが返信されたことを確認すると、図１３に示すようにデータベース３の配信先情報（「store_target」テーブル）の未送信を示すフラグ（already_sent）の「false 」を「true」へ書き換え、pubrelメッセージをクライアント装置２へ送信する。配信先情報は、パケットＩＤは、pulish メッセージ送信時に採番された「0x102 」によって更新されている。そして図１４に示すようにサーバ装置１は、pubrelメッセージに対してクライアント装置２からのpubcomp メッセージの受信を確認するとここで初めて、データベース３（「store_target」テーブル及び「store 」テーブル）からクライアント装置２（s1）向けの識別子「123 」を含む保存メッセージを消去する。サーバ装置（b1）がpubcomp メッセージを受信する前に、切断された場合、配信先情報は送信したか否かを示すフラグが送信済み（already_sent=true ）を示したままデータベース３に保存されている。再確立後、サーバ装置（b1）は、再度pubrelメッセージの送信から処理を再開する。このとき配信先情報のパケットＩＤを参照してpubrelメッセージを送信している。後述の中途メッセージ情報による送信と重複する場合でも、パケットＩＤを保存しておき、再送時に利用することで、受信側で同一メッセージを棄却することができ、「Exactry once」を実現することができる。
【００６０】
図６から図１４に示したように、サーバ装置１はデータベース３（「store 」テーブル及び「store_target」テーブル）に記憶する情報を利用したkeep接続を実現する動作を行なう。これにより、仲介するブローカの実体が１つである場合のセッションの切断に対するサブスクライバまでのメッセージの到達の保証は実現される。
【００６１】
keep接続が選択されている場合サーバ装置１は更に、QoS =1又は=2で接続しているクライアント装置２との間で、図３に示したMQTTモデルにおける到達保証用のメッセージのやり取り中にセッションが切断されたケースを考慮した処理を行なう。
【００６２】
図１５Ａは、サーバ装置１がセッション切断を検知した際に実行する処理手順の一例を示すフローチャートである。なお図１５Ａ及び図１５Ｂの処理手順は、図３Ａから図３Ｃに示した送信者側であるサーバ装置１における手順である。図１５Ａのフローチャートに示す処理手順は、図４のフローチャートに示した処理手順の内、ステップＳ１０の後に実行される。
【００６３】
サーバ装置１の制御部１０は、publish/pubrelメッセージを送信する際に詳細には、送信するメッセージをMQTT準拠のネットワークコントローラ（通信ライブラリ）の送信用ボックス（以下送信バッファ）にそのパケットを書き込む。ネットワークコントローラの動作により、送信用ボックスに書き込まれたパケットが対応するセッションの相手へのソケットに書き込まれ、送信が行なわれる。そしてネットワークコントローラの動作により、メッセージに対して応答されるべきメッセージ（puback/pubrec, pubcomp）を受信するとこの送信バッファからpublish/pubrelメッセージを消去する処理が行なわれる。
【００６４】
制御部１０は、サブスクライバであるクライアント装置２との切断を検知すると（ステップＳ１０１）、送信バッファにメッセージが残存しているか否かを判断する（ステップＳ１０２）。残存していると判断された場合（Ｓ１０２：ＹＥＳ）、制御部１０はその残存しているメッセージのパケットイメージをそのまま読み出し、データベース３（「keep_mqtt 」テーブル）に中途メッセージ情報として記憶する（ステップＳ１０３）。中途メッセージ情報は、送信先のクライアント装置２の識別情報（user_id ）と、送信時刻（タイムスタンプ= [TS]）と、メッセージのパケットイメージそのままとを含む。パケットイメージには、クライアント装置２へのメッセージ送信時に付与したパケットＩＤ、QoS 等が含まれている。送信バッファに残存しているメッセージは、セッションが切断（破棄）されると、対応するメッセージを受信していないにも拘わらず削除（破棄）され（ステップＳ１０４）、処理を終了する。
【００６５】
ステップＳ１０２にて残存していないと判断された場合（Ｓ１０２：ＮＯ）、制御部１０は、そのまま処理を終了する。
【００６６】
図１５Ｂは、サーバ装置１がセッション再開を検知した際に実行する処理手順の一例を示すフローチャートである。図１５Ｂのフローチャートに示す処理手順は、図４のフローチャートに示した処理手順の内、ステップＳ１８の前に実行される。
【００６７】
制御部１０は、クライアント装置２からの通信接続を検知する（ステップＳ１０５）。制御部１０は、通信接続の相手を特定して状態情報を復元しているので、中途メッセージ情報として、再接続してきたクライアント装置２（接続相手）を対象とする送信途中のメッセージがデータベース３（「keep_mqtt 」テーブル）に記憶されているか否かを判断する（ステップＳ１０６）。ステップＳ１０５にて記憶されていないと判断された場合（Ｓ１０６：ＮＯ）、制御部１０は処理をそのまま次のステップＳ１８へ進める。
【００６８】
ステップＳ１０５で記憶されていると判断された場合（Ｓ１０６：ＹＥＳ）、制御部１０は、データベース３に中途メッセージとして記憶してあった送信時のパケットイメージをそのまま、再接続してきたクライアント装置２へ送信する（ステップＳ１０７）。制御部１０は、データベース３から読み出した中途メッセージを送信すると、データベース３（「keep_mqtt 」テーブル）から該当する中途メッセージの記憶を削除し（ステップＳ１０８）、再開時の再送の処理を終了する。中途メッセージの記憶の削除タイミングはこれに限らず、対応するメッセージ（puback/pubrec ）を受信した場合など、適切に設計される。
【００６９】
図１６から図１９を参照して図１５Ａ及び図１５Ｂのフローチャートにおける処理を説明する。図１６は、クライアント装置２がサーバ装置１と切断された状態を示す図である。なお図１６はQoS =1に調停されている例を示す。図１６に示すように、ブローカであるサーバ装置１（b1）がクライアント装置２（s1）へpublish メッセージを送信した後、pubackメッセージが返される前にセッションが切断されると（Ｓ１０１）、サーバ装置１（b1）の制御部１０は、送信バッファにpublish メッセージが残存していると判断する（Ｓ１０２：ＹＥＳ）。したがって、サーバ装置１（b1）はデータベース３（「keep_mqtt 」テーブル）に、publish メッセージを中途メッセージとして記憶する（Ｓ１０３）。図１６では具体的には、タイムスタンプ（[TS]）、クライアント装置（s1）の識別情報（s1）、publish メッセージ（topic=t1, packet_id=0x101, data/payload=a, qos=1）がそのまま記憶されている。これによりサーバ装置１（b1）では、pubackメッセージを受信していないために残存していたpublish メッセージが送信バッファから削除される（Ｓ１０４）。
【００７０】
図１７は、図１６の切断状態から復帰した場合の処理手順を示す図である。クライアント装置２（s1）が、サーバ装置１（b1）又は他のサーバ装置１に通信接続すると、サーバ装置１（b1又は他）ではこれを検知し（Ｓ１０５）、クライアント装置２（s1）向けのメッセージが、データベース３（「keep_mqtt 」テーブル）に中途メッセージ情報として記憶されているか否かを判断する（Ｓ１０６）。図１６のケースでは、クライアント装置２（s1）向けのpublish メッセージが記憶されているので、通信接続先のサーバ装置１（b1）の制御部１０はこれをデータベース３（「keep_mqtt 」テーブル）から読み出し、パケットＩＤ等をそのまま含むパケットとして再送する（Ｓ１０７）。データベース３（「keep_mqtt 」テーブル）からは一旦、中途メッセージとして記憶されていたpublish メッセージが削除される（Ｓ１０８）。クライアント装置２（s1）は、publish メッセージの再送を受け、pubackメッセージを送信する。pubackメッセージが送信完了された状態では、サーバ装置１側の送信バッファからも、データベース３（「keep_mqtt 」テーブル）における中途メッセージ情報からも、未送信であったメッセージが削除されて初期状態に戻る。これにより、メッセージのやり取りの途中で切断がされた場合に、サブスクライバであるクライアント装置２がいずれのサーバ装置１に再接続したとしても、その中断されていたMQTTにおける到達保証に係るメッセージのやり取りが完了する。
【００７１】
図１８は、クライアント装置２がサーバ装置１と切断された他の状態の例を示す図である。なお図１８はQoS =2に調停されている例を示す。調停後のQoS が「２」である場合（パブリッシャからのメッセージ送信時の指定及びサブスクライバからの指定がいずれも「２」）、ブローカであるサーバ装置１とサブスクライバであるクライアント装置２との間のセッションで考慮すべきメッセージのやり取りが未完了状態における切断のパターンは、符号Ｘで示すpubrecメッセージの受信前、及び符号Ｙで示すpubcompメッセージの受信前である。符号Ｘで示すpubrecメッセージの受信前においては、図１６で示した処理同様に、サーバ装置１にて送信バッファにpublish メッセージが残存していると判断されるので（Ｓ１０２：ＹＥＳ）、データベース３（「keep_mqtt 」テーブル）に、中途メッセージ情報として、クライアント装置２（s1）向けのpublish メッセージのパケットイメージが記憶される（Ｓ１０３）。送信バッファからもpublish メッセージが削除される（Ｓ１０４）。そして符号Ｙで示すpubcomp メッセージの受信前においては、サーバ装置１にて送信バッファにpubrelメッセージが残存していると判断されるので（Ｓ１０２：ＹＥＳ）、データベース３（「keep_mqtt 」テーブル）に、中途メッセージ情報としてクライアント装置２（s1）向けのpubrelメッセージのパケットイメージが記憶される（Ｓ１０３）。
【００７２】
図１９は、図１８の切断状態から復帰した場合の処理手順を示す図である。この場合も、クライアント装置２（s1）がサーバ装置１（b1）又は他のサーバ装置１に通信接続すると、サーバ装置１（b1又は他）ではこれを検知し（Ｓ１０５）、クライアント装置２（s1）向けのメッセージがデータベース３（「keep_mqtt 」テーブル）における中途メッセージ情報に記憶されているか否かを判断する（Ｓ１０６）。図１８の符号Ｘのタイミングで切断されていたところから復帰した場合には、クライアント装置２（s1）向けのpublish メッセージが中途メッセージ情報として記憶されているので、接続先のサーバ装置１（b1）の制御部１０はこれをデータベース３（「keep_mqtt 」テーブル）から読み出し、パケットＩＤ等をそのまま含むパケットとして再送する（Ｓ１０７）。符号Ｙのpubrecメッセージの受信前のタイミングで切断されていたところから復帰した場合には、クライアント装置２（s1）向けのpubrelメッセージが記憶されている。サーバ装置１（b1）の制御部１０はこれをデータベース３（「keep_mqtt 」テーブル）から読み出し、パケットＩＤ等をそのまま含むパケットとして再送する（Ｓ１０７）。これに対しクライアント装置２（s1）では、再接続した後にpublish メッセージの再送を受信した場合、これを既に受信処理している場合には破棄してpubrecメッセージを返信する。pubrelメッセージの再送を受信した場合には、pubcomp メッセージをサーバ装置１へ返信する。
【００７３】
同様にして、サーバ装置１（b1）は、パブリッシャであるクライアント装置２との間のセッションがpuback/pubrecメッセージ又はpubcomp メッセージの送信を完了する前に切断された場合には、クライアント装置２（s1）向けの、データベース３（「keep_mqtt 」テーブル）における中途メッセージ情報としてこれを記憶する。パブリッシャであるクライアント装置２（s1）が再接続してきた場合、サーバ装置１（b1）の制御部１０は、このデータベース３（「keep_mqtt 」テーブル）を参照して通信相手先へのメッセージが記憶されている場合にはパケットイメージをそのまま送信する。
【００７４】
このようにMQTTモデルの処理手続きを実行中に切断が検知された場合、データベース３（「keep_mqtt 」テーブル）にメッセージが中途メッセージ情報として記憶される。これにより、再度セッションが確立されたときにその直前の状態に復元される。仮に、サブスクライバであるクライアント装置２（s1）が異なるサーバ装置１へ通信接続を行なったとしても、データベース３（「keep_mqtt 」テーブル）に記憶されている中途メッセージ情報は各サーバ装置１で共有し同期し合うので同一の状況を復元させることが可能である。
【００７５】
（３）ブローカ間の通信接続
通信システム１００では、図１に示したようにブローカである複数のサーバ装置１が例えば数十台、相互にメッシュ状に通信接続する。サーバ装置１はブローカとして起動すると最初に、接続可能な他のサーバ装置１と通信接続を確立し、自身に通信接続しているクライアント装置２の情報（「connections」テーブル）を交換し、共有のデータベース３から参照して情報の同期処理を行なう。また、サーバ装置１間の接続は、いずれも上述のkeep接続で実現する。なおサーバ装置１は、自身に通信接続しているクライアント装置２が指定するトピックについて、サブクライブを実行する。実行先は、指定トピックのパブリッシャが通信接続している他のサーバ装置１である。サーバ装置１はいずれの場合もQoS を「２（Exactly once）」で指定する。サーバ装置１間のセッションが切断された場合、その間に自身に接続しているクライアント装置２が必要とするメッセージが送信されたとしても、他のサーバ装置１が保持していたものを取得して配信することが可能である。
【００７６】
［２．複数の保証レベル］
本実施の形態における通信システム１００でサブスクライバまでのメッセージの到達保証は、全てのセッションが切断されずに安定的に維持している場合には、サーバ装置１間のkeep接続及びサーバ間におけるQoS =2の設定によって実現される。到達保証を妨げる要因は、セッションの切断、及びブローカであるサーバ装置１のダウンである。keep接続のみならず到達保証のために、後述するようにデータベース３を用いるが、データベース３のダウンについては冗長化によってこれを保証する。本実施の形態における通信システム１００では、複数のブローカを経由するネットワークＮ上で、publish メッセージの送信時、又はサブスクライブ時に指定されたQoS レベルと、ブローカにおけるダウン時の動作選択に応じてメッセージ（データ）の到達を保証する。
【００７７】
ブローカであるサーバ装置１は、自身がダウンした場合、即ちサーバ装置１の実体がエラーにより消失、又は処理が停止することでプロセスが終了させられた場合に、それまでのメッセージ処理を保証するか否かを、起動時に選択する。サーバ装置１は、ダウンした場合にも保証する場合には、全ての処理をデータベース３に記憶することを前提とする。
【００７８】
QoS はクライアント装置２が通信接続しているブローカであるサーバ装置１へpublish メッセージを送信する都度、又はサブスクライブするトピックを指定する際に選択するオプションの１つであり、サーバ装置１はこれを認識して以後の処理を実行する。なお、サブスクライバであるクライアント装置２の指定トピックについてのQoS は、サブスクライブが解除されない限り維持される。
【００７９】
選択に応じた処理内容を順に説明する。保証レベルは以下のようになる。
（１）QoS =0（ゼロ）
（２）QoS =1、ただしブローカがダウンした場合は保証しない
（３）QoS =1、ブローカがダウンした場合も保証する
（４）QoS =2、ただしブローカがダウンした場合は保証しない
（５）QoS =2、ブローカがダウンした場合も保証する
【００８０】
（１）QoS =0（ゼロ）
パブリッシャであるクライアント装置２から、QoS =0（ゼロ）でメッセージが送信される場合の該メッセージについての各装置における送信に係る処理について説明する。パブリッシャであるクライアント装置２から、QoS =0を指定してpublish メッセージが送信された場合、サーバ間のサブスクライブのQoS =2の設定、及びサブスクライバであるクライアント装置２からの指定トピックについてのQoS の指定に拘わらず、このメッセージの経路である全てのセッションにてQoS が「０（ゼロ）」に調停される。この場合、送信されたpublish メッセージに基づき、ブローカであるサーバ装置１はこのメッセージを指定トピックとしてサブクライブしているクライアント装置２又は他のサーバ装置１へ各１回送信するのみである。ブローカ間でも図３Ａに示したpublish メッセージの送信のみが行なわれ、pubackメッセージ、pubrec/pubrel/pubcompメッセージのやり取りは行なわれない。
【００８１】
サブスクライバであるクライアント装置２が、指定トピックについてQoS として「０（ゼロ）」を指定した場合、ブローカであるサーバ装置１から当該クライアント装置２へのメッセージのQoS は「０（ゼロ）」である。当該クライアント装置２へメッセージを送信するサーバ装置１は、該クライアント装置２が指定したトピックのpublish メッセージをパブリッシャ又は他のサーバ装置１から受信する都度、publish メッセージを該クライアント装置２へ向けて１回のみ送信して送受信処理を終了する。なおこの場合、パブリッシャであるクライアント装置２と該クライアント装置２が通信接続しているブローカとの間のメッセージの送受信、及び、ブローカ間のメッセージの送受信は、パブリッシャから指定されているQoS （1 or 2）に基づき行なわれる。
【００８２】
（２）QoS =1、ブローカダウン保証外の動作
ブローカがダウンした場合にメッセージの到達を保証しないという前提において、パブリッシャであるクライアント装置２から、QoS =1を指定してpublish メッセージが送信される場合の処理について説明する。なお以下の説明では、当該メッセージのトピックを指定しているサブスクライバであるクライアント装置２が、トピック指定時にQoS として「１」以上を指定している場合の当該サブスクライバまでのメッセージの到達について説明する。サーバ間のサブスクライブのQoS =2の設定、及びサブスクライバであるクライアント装置２からの指定トピックについてのQoS が「１」以上であるケースでは、それらのQoS の指定に拘わらず、このQoS =1のメッセージの経路である全てのセッションにてQoS が「１」に調停される。トピック指定時に「０（ゼロ）」を指定しているサブスクライバへのメッセージ送信は（１）で述べたようにpublish メッセージを１回送信するのみで処理が終了するので説明を省略する。
【００８３】
（２．１）正常運用時
まず、QoS =1のメッセージに対する各サーバ装置１における処理の順序性について述べる。サーバ装置１は、第１記憶部１１に記憶しているサーバプログラム１Ｐに基づき、パブリッシャであるクライアント装置２からメッセージの送信を受けた場合、指定されたQoS に応じてパブリッシャへ応答（pubackメッセージ）を返す。この応答のタイミングはMQTTモデルであれば、セッション毎に順序が守られればよい（図３参照）。これに対し通信システム１００におけるサーバ装置１は、パブリッシャから送信されたpublish メッセージに基づきサブスクライバであるクライアント装置２又は他のブローカであるサーバ装置１との間のメッセージ送受信タイミングに対する順序性を持たせてパブリッシャへの応答を返す。
【００８４】
図２０は、ブローカであるサーバ装置１によるメッセージ配信の処理手順の一例を示すフローチャートである。なお図２０のフローチャートに示す処理手順は、図４のフローチャートに示した手順の内のステップＳ９の詳細に対応する。
【００８５】
サーバ装置１の制御部１０は、パブリッシャとして通信接続を確立している１又は複数のクライアント装置２から、又は他のサーバ装置１からpublish メッセージを受信したか否かを判断する（ステップＳ２０１）。受信していないと判断された場合（Ｓ２０１：ＮО）、制御部１０は処理をステップＳ２０１へ戻す。
【００８６】
制御部１０は、受信したと判断した場合（Ｓ２０１：ＹＥＳ）、受信したpublish メッセージのトピックを抽出し（ステップＳ２０２）、抽出されたトピックを指定してサブスクライブしている他の装置に、他のサーバ装置１が含まれているか否かを判断する（ステップＳ２０３）。
【００８７】
ステップＳ２０３にて他のサーバ装置１は含まれていないと判断された場合（Ｓ２０３：ＮＯ）、制御部１０は、自身に通信接続しており、抽出されたトピックを指定しているサブスクライバであるクライアント装置２へ向けてステップＳ２０１で受信したpublish メッセージを送信する（ステップＳ２０４）。なおステップＳ２０４において制御部１０は、送信先に、keep接続を選択しており且つセッションが切断中であるクライアント装置２が存在する場合には、送信先をデータベース３とする。続いて制御部１０は、受信したpublish メッセージの送信元（パブリッシャ又は他のサーバ装置１）へpubackメッセージを返し（ステップＳ２０５）、publish メッセージの配信処理を終了する。ステップＳ２０４において、抽出されたトピックを指定していたサブスクライバが通信接続を切断しているなどして、データベース３に書き込む場合には、データベース３への書き込みが行なわれる。
【００８８】
他のサーバ装置１が含まれていると判断された場合（Ｓ２０３：ＹＥＳ）、制御部１０は、抽出されたトピックを指定しているサブスクライバであるクライアント装置２及び他のサーバ装置１へステップＳ２０１で受信したpublish メッセージを送信する（ステップＳ２０６）。ステップＳ２０６においてもデータベース３が配信先となる場合には送信に代替してデータベース３への書き込みが行なわれる。
【００８９】
制御部１０は、ステップＳ２０６のpublish メッセージの送信先の内、他のサーバ装置１全てからpubackメッセージを受信したか否かを判断する（ステップＳ２０７）。実行先のサーバ装置１全てからpubackメッセージを受信しないと判断された場合（Ｓ２０７：ＮＯ）、制御部１０は受信するまでpubackメッセージの送信は待機する。
【００９０】
ステップＳ２０７にて実行先のサーバ装置１全てからpubackメッセージを受信したと判断された場合（Ｓ２０７：ＹＥＳ）、制御部１０はステップＳ２０１で受信したメッセージの送信元のパブリッシャ又は他のサーバ装置１へpubackメッセージを返し（ステップＳ２０８）、publish メッセージの配信処理を終了する。
【００９１】
図２０のフローチャートに示した手順にて注目すべきは、抽出されたトピックについてpublish メッセージを送信する際に、送信先に当該トピックをサブスクライブしている他のサーバ装置１が１又は複数存在する場合には（Ｓ２０３：ＹＥＳ）、その他のサーバ装置１全てからpubackメッセージを受信するまでは（Ｓ２０７：ＹＥＳ）、メッセージの送信元のパブリッシャ又は他のサーバ装置１へpubackメッセージを返さない点である。送信先に他のサーバ装置１が含まれない場合、ステップＳ２０５に示したように直ちにpubackメッセージを送信することと異なり、この点によって順序性が持たれる。これにより、クライアント装置２へは送信処理が完了したことが保証され、他のサーバ装置１を経由する場合でもその先のクライアント装置２への送信処理が完了したことが保証される。
【００９２】
なお、他のサーバ装置１全てからpubackメッセージを受信するまでは（Ｓ２０７：ＹＥＳ）、メッセージの送信元のパブリッシャ又は他のサーバ装置１へpubackメッセージを返さないという制御については、各サーバ装置１に複数のクライアント装置２が通信接続しており、そして多数のトピックについて多数のメッセージが前後して送受信されることを鑑みると具体的には以下のように行なうことが好ましい。制御部１０は、publish メッセージを受信すると、この１つのメッセージに対応するカウント数を初期化し、この１つのメッセージのトピックを指定トピックとするクライアント装置２及びサーバ装置１への送信処理を通信部１４により実行し、送信処理の都度、カウント数を増大させる。そして、クライアント装置２へ送信する場合にはpublish メッセージの送信処理（ソケットへの書き込み）の完了が検知された時点で対象のカウント数を減少させ、データベース３に書き込む場合には書き込みの完了が検知された時点で対象のカウント数を減少させる。複数のクライアント装置２へのpublish メッセージを送信する場合、各々へのソケット書き込みの都度増大したカウント数は、全てのクライアント装置２への送信完了が検知されると、増大した分だけ減少している。送信先に他のサーバ装置１が含まれない場合、全てのクライアント装置２への送信完了が検知されて、カウント数が初期値となった時点で該１つのメッセージの送信元へpubackメッセージが送信される。他のサーバ装置１が含まれる場合、他のサーバ装置１への送信処理について完了した場合には、カウント数は増大したままである。他のサーバ装置１からのpubackメッセージの受信が検知できたタイミングで制御部１０は、該１つのメッセージに対応するカウント数を減少させ、他のサーバ装置１全てからpubackメッセージを受信したことでカウント数が初期値になった時点で該１つのメッセージの送信元へpubackメッセージを送信する。
【００９３】
図２０のフローチャートに示した手順について具体的に説明する。図２１は送信順序を示す説明図である。図２１の説明図では、パブリッシャであるクライアント装置２と該パブリッシャから送信されるメッセージのトピックを指定トピックとしているサブスクライバであるクライアント装置２との間に、１つのブローカのみが介在する例を挙げて説明している。図２１の説明図では各メッセージの表記に対し、その順序を示す数値を付している。数値が小さいほど時間的に先に実行されるものであり、同一のものは同時でもよいし前後を問わないことを意味している。図２１に示す例では具体的には、最初（（10）のタイミング）に、クライアント装置２（p1）からpublish メッセージが送信される。これに応じてサーバ装置１は、このメッセージのトピック「t1」を指定トピックとしたサブスクライバであるクライアント装置２（s1）へメッセージの送信タイミング（20）よりも後の（30）のタイミングに、クライアント装置２（p1）へpubackメッセージを返す。クライアント装置２（s1）から、pubackメッセージが返されるか否かはクライアント装置２の設計次第であって不明であるから、サーバ装置１（b1）はこれを待つことなくpubackメッセージをパブリッシャであるクライアント装置２（p1）へ返している。
【００９４】
また、パブリッシャであるクライアント装置２と通信接続しているサーバ装置１は、自身に他のブローカであるサーバ装置１が接続している場合、前記パブリッシャが送信するpublish メッセージのトピックを指定する他のサーバ装置１へメッセージを送信する。そして通信システム１００におけるサーバ装置１は、他のサーバ装置１がpubackメッセージを返してくるのを待ってから、パブリッシャへpubackメッセージを返す。他のサーバ装置１（１又は複数）は、夫々に接続しているサブスクライバであるクライアント装置２へ向けて、対応するpublish メッセージを送信した後にpubackメッセージを返してくる。なお通信システム１００においてサーバ装置１間の接続は全て、上述したようにkeep接続である。
【００９５】
図２２は送信順序の他の例を示す説明図である。図２２の説明図では、パブリッシャであるクライアント装置２（p1）と該パブリッシャから送信されるメッセージのトピックを指定トピックとしているサブスクライバであるクライアント装置２（s1）との間に、２つのブローカが介在する例を挙げて説明している。図２２の説明図では各メッセージに、順序を示す数値を付している。数値が小さいほど時間的に先に実行されるものであり、同一のものは同時でもよいし前後を問わないことを意味している。
【００９６】
図２２に示す例では具体的には、最初のタイミング（10）に、クライアント装置２（p1）からQoS =1を指定してpublish メッセージが送信される場合について説明する。サーバ装置１（b1）は、クライアント装置２（p1）から送信されたpublish メッセージを、自身に接続している他のサーバ装置１（b2及びb3）へ、（20）のタイミングで送信する。他のサーバ装置１、例えばサーバ装置１（b2）は、サーバ装置１（b1）から送信されたpublish メッセージを受信すると、そのトピック「t1」を指定トピックとしたサブスクライバであるクライアント装置２（s1）へpublish メッセージをタイミング（30）に送信してから、サーバ装置１（b1）へタイミング（40）でpubackメッセージを返す。クライアント装置２（s1）から、（40）のタイミングでpubackメッセージが返されるか否かはクライアント装置２の設計次第であって不明であるから、サーバ装置１（b2）はこれを待つことなくpubackメッセージを返している。サーバ装置１（b1）は、トピック「t1」のメッセージを送信したサーバ装置１（b2及びb3）のいずれからも（40）のタイミング前後でpubackメッセージが返されてきたか否かを判断する。サーバ装置１（b1）は、トピック「t1」についてのメッセージの送信先である全てのサーバ装置１（b2及びb3）からpubackメッセージが返されたことを確認した場合に、パブリッシャであるクライアント装置２（p1）へ、（50）のタイミングでpubackメッセージを返す。これにより、パブリッシャであるクライアント装置２（p1）は、（50）のタイミングでpubackメッセージをサーバ装置１（b1）から受信できたことで、これを指定トピックとするサブスクライバであるクライアント装置２へのpublish メッセージが到達したこと（受信確認ではない）を認識することができる。この意味で、通信システム１００では、セッション毎の到達保証のみならず、サブスクライバまでのメッセージの到達をQoS =1で保証することが可能になる。
【００９７】
（２．２）切断発生時
ブローカがダウンした場合は保証しないという前提で、QoS =1が指定されたpublish メッセージが送信され、全てのセッションにてQoS が「１」に調停されるケースにおける切断時の処理について切断箇所毎に説明する。図２３は、サーバ装置１及びクライアント装置２の接続構成を示す図である。図２３は、パブリッシャであるクライアント装置２（p1）と該パブリッシャから送信されるメッセージのトピックをQoS =1で指定トピックとしているサブスクライバであるクライアント装置２（s1）との間に、２つのブローカが介在する場合の接続構成を示している。図２３の接続構成では、パブリッシャであるクライアント装置２（p1）は、ブローカであるサーバ装置１（b1）に通信接続している（セッションＥ）。サブスクライバであるクライアント装置２（s1）はもう１つのブローカであるサーバ装置１（b2）に通信接続している（セッションＦ）。２つのブローカ間も通信接続されている（セッションＧ）。
【００９８】
（２．２．１）パブリッシャ・ブローカ間
図２３中のセッションＥが切断された場合の到達保証について説明する。パブリッシャであるクライアント装置２から、QoS =1が指定されたpublish メッセージが送信された場合におけるパブリッシャとブローカとの間（セッションＥ）の通信の切断については、パブリッシャであるクライアント装置２（p1）からpublish メッセージが送信された後に切断されるケースを考える。
【００９９】
このケースでは、パブリッシャであるクライアント装置２（p1）は、送信したpublish メッセージに対するpubackメッセージが返されるまで、そのpublish メッセージを送信バッファに一時記憶したままとする（図３）。なおサーバ装置１（b1）は、切断される前に受信したpublish メッセージについて、他のサーバ装置１（b2）へのpublish メッセージの送信を完了し、（40）のタイミングにて他のサーバ装置１（b2）からpubackメッセージを受信し、pubackメッセージを送信しようとしていた可能性がある。しかしながらサーバ装置１（b1）は、セッションＥが切断されているのでこのpubackメッセージを送信できない。
【０１００】
クライアント装置２（p1）は、ブローカであるサーバ装置１（ここではb1、他のブローカでもよい）へ通信接続のリクエストを実行する。リクエストに応じてセッションＥが確立するとクライアント装置２（p1）は、送信バッファに一時記憶しているpublish メッセージを新たなセッションにおいて接続先のサーバ装置１（b1）へ送信する。接続先のサーバ装置１（b1）は、再接続してきたクライアント装置２から再送されたpublish メッセージについて、新たなpublish メッセージであるとして処理を行なう。この場合でもQoS =1の処理では問題なく到達保証が達成され、パブリッシャであるクライアント装置２（p1）ではサブスクライバであるクライアント装置２（s1）へメッセージが送信されたことを認識することができる。
【０１０１】
（２．２．２）ブローカ・サブスクライバ間
図２３中のセッションＦが切断された場合の到達保証について説明する。セッションＦが、サーバ装置１（b2）がクライアント装置２（s1）へ（30）のタイミングにてpublish メッセージを送信する前に切断された場合、keep接続の処理（図１０から図１２）により、再接続後にデータベース３から配信される。
【０１０２】
図２３中のセッションＦが、クライアント装置２（s1）からサーバ装置１（b2）へ（40）のタイミングにてpubackメッセージを送信する前に切断された場合、データベース３（「keep_mqtt 」テーブル）の中途メッセージ情報を参照した処理（図１５から図１７）により、中断されたやり取りが再開され、メッセージのやり取りが完了する。
【０１０３】
（２．２．３）ブローカ・ブローカ間
ブローカ間のセッションは上述したようにkeep接続が選択されている。図２４は、ブローカ間が切断された場合のサーバ装置１における処理手順の一例を示すフローチャートである。なお図２４のフローチャートに示す処理は基本的に、パブリッシャ側のサーバ装置１（即ち図３における送信者側）によって実行されるものである。サブスクライバ側のサーバ装置１の処理は、一部省略して実行される。
【０１０４】
サーバ装置１の制御部１０は、他のサーバ装置１とのセッション切断を検知すると（ステップＳ３０１）、他のサーバ装置１にサブスクライバとしてkeep接続しているクライアント装置２をデータベース３（「keep_sub」テーブル）のセッション情報から抽出する（ステップＳ３０２）。
【０１０５】
制御部１０は、抽出したクライアント装置２の状態情報を、自身に接続しているクライアント装置２として扱って一時記憶する（ステップＳ３０３）。ただしこのクライアント装置２についてはメッセージの配信先をデータベース３に設定する（keep接続後の切断状態と同様、図８参照）。そして制御部１０は、図１５Ａのフローチャートに示した処理手順にしたがって、他のサーバ装置１（サブスクライバ側）向けのpublish メッセージが送信バッファに残存しているか否かを判断する（ステップＳ３０４）。残存していると判断された場合（Ｓ３０４：ＹＥＳ）、制御部１０はこのpublish メッセージを、中途メッセージ情報としてでなく、本来であれば他のサーバ装置１とセッションを確立しているクライアント装置２へ送信されていたはずのメッセージとしてデータベース３に保存する（ステップＳ３０５）。送信バッファに残存していたpublish メッセージは消去される。制御部１０は、メッセージをデータベース３に保存したことからpubackメッセージを元のpublish メッセージの送信元（パブリッシャ側）へ送信する（ステップＳ３０６）。このときデータベース３（「store 」テーブル）には、publish メッセージに含まれるペイロードが識別子と共に保存メッセージとして記憶される。そしてこの保存メッセージの配信先情報として、切断されている他のサーバ装置１を経由したサブスクライバへ送信すべきことを示す情報がデータベース３（「store_target_broker_user」テーブル）に記憶される。このブローカ経由の配信先情報には、情報の識別子（ID）、切断を検知したサーバ装置１の識別情報（broker_id ）、切断されている他のサーバ装置１向けに送信した際に使用したパケットＩＤ（broker_pid）、送信先のクライアント装置２の識別情報（user_id ）及び送信するはずだった保存メッセージの識別子（store_id）を含む。またブローカ経由の配信先情報には、後述のQoS =2の処理で用いられる再送時のパケットＩＤ（pid 、再送しているか否か）、及び再送先への送信が完了したか（already_sent他のサーバ装置１からpubrecメッセージを受信しているか）の情報が含まれる。なおテーブル名は例示であることは勿論である。
【０１０６】
ステップＳ３０４で残存していないと判断された場合（Ｓ３０４：ＮＯ）、publish メッセージに対するpubackメッセージを受信済み、そして元のpublish メッセージの送信元（パブリッシャ側）へpubackを送信済みであるので、そのまま処理を次のステップＳ３０７へ進める。
【０１０７】
サーバ装置１の制御部１０は、該他のサーバ装置１とのセッションを再び確立すると（ステップＳ３０７）、「（１．３．）ブローカ間の通信接続」で述べたようにブローカ間の同期処理を実行する（ステップＳ３０８）。なお、切断が検知されてから再度セッションが確立するまでの期間は大抵１０秒以内、例えば３から５秒である。なお制御部１０は、再確立されたブローカ間のセッションはすべて新規のものとして確立され、切断前のセッションにおいて採番していたパケットＩＤ等は全てリフレッシュされる。
【０１０８】
サーバ装置１の制御部１０は、自身に接続しているとして一時記憶しているサブスクライバであるクライアント装置２の識別情報と、データベース３に記憶されている各クライアント装置２の接続先の情報（「connections 」）とを照合する（ステップＳ３０９）。なお接続先の情報（「connections 」）はサーバ装置１がクライアント装置２とセッションを確立する毎に記憶する情報であって、クライアント装置２（サブスクライバ及びパブリッシャ両方）がいずれのサーバ装置１に通信接続しているかを記憶した情報である。keep接続しているクライアント装置２についての接続先の情報は切断されても、非keep接続がされるまでデータベース３に保持される。なお通信接続先が変更となった場合は、接続先のサーバ装置１の識別情報で上書きされる。
【０１０９】
サーバ装置１の制御部１０は、ステップＳ３０８の照合の結果、自身に通信接続しており状態情報がonlineであるクライアント装置２（複数存在する場合は夫々）について、データベース３に記憶されている接続先の情報に基づき、接続先が自身であるか否かを判断する（ステップＳ３１０）。
【０１１０】
自身でないと判断された場合（Ｓ３１０：ＮＯ）、制御部１０は、自身に接続しているクライアント装置２の情報の内、対象のサブスクライバであるクライアント装置２の情報を削除し（ステップＳ３１１）、再開時の処理を終了する。
【０１１１】
ステップＳ３１０で自身であると判断された場合（Ｓ３１０：ＹＥＳ）、制御部１０はステップＳ３０４で残存していると判断されていたか否かを判断する（ステップＳ３１２）。残存していると判断されていた場合（Ｓ３１２：ＹＥＳ）、制御部１０はステップＳ３０５にて送信されていたはずの保存メッセージを読み出し（ステップＳ３１３）、サブスクライバであるクライアント装置２へ送信する（ステップＳ３１４）。制御部１０は、その後送信先のクライアント装置２からpubackメッセージを受信し（ステップＳ３１５）、配信先情報及び保存メッセージを削除する（ステップＳ３１６）。ステップＳ３１２で残存していると判断されていなかった場合（Ｓ３１２：ＮＯ）、制御部１０はそのまま、セッションの再確立時のメッセージの処理を終了する。
【０１１２】
サブスクライブ側のサーバ装置１では、ステップＳ３０２、Ｓ３０３は省略して実行される。
【０１１３】
図２４のフローチャートに示した処理について、具体的に説明する。図２５から図２７は、図２３に示した接続構成におけるブローカ間のセッションＧが切断された場合の処理の例を示す説明図である。図２５には、セッションＧが切断された場合にデータベース３に記憶される情報の内容例を示している。サーバ装置１（b1）は、タイミング（10）におけるパブリッシャからのメッセージに基づき（20）のタイミングで、サーバ装置１（b2）へ向けてpublish メッセージを送信する。サーバ装置１（b1）は、送信先のサーバ装置１（b2）とのセッションの切断を検知する（Ｓ３０１）。サーバ装置１（b1）は、切断されたセッションの接続先のサーバ装置１（b2）にサブスクライバとして通信接続されているはずのクライアント装置２（s1）の識別情報をデータベース３（「keep_sub」テーブル）から抽出する（Ｓ３０２）。サーバ装置１（b1）は、クライアント装置２の識別情報「s1」の状態情報を、配信先をデータベース３に指定して一時記憶する（Ｓ３０３）。（20）のタイミングで送信したpublish メッセージは、pubackメッセージを受信できていないために送信バッファに残存しており（Ｓ３０４：ＹＥＳ）、サーバ装置１（b1）は残存しているpublish メッセージを読み出し、サーバ装置１（b2）から送信されていたはずのメッセージ（保存メッセージ及びブローカ経由の配信先情報）としてデータベース３（「store 」テーブル及び「store_target_broker_user」テーブル）に記憶する（Ｓ３０５）。図２５の例では、識別子「345 」の保存メッセージと、この保存メッセージの識別子「345 」を含むブローカ経由の配信先情報（broker_id=b1, broker_pid=0x123, user_id=s1, pid=NULL, store_id=345, already_sent=false）が記憶されている。そしてサーバ装置（b1）は、publish メッセージをデータベース３に保存したので、（30）のタイミングでパブリッシャであるクライアント装置（p1）へpubackメッセージを送信している。これによりサーバ装置１（b1）では、全てのサーバ装置１経由でメッセージを送信できたことを保証した上でパブリッシャであるクライアント装置２へpubackメッセージを返すことができる。
【０１１４】
なおこのとき、クライアント装置２（s1）が接続しているブローカであるサーバ装置１（b2）で、サーバ装置１（b1）からのpublish メッセージをセッションＧの切断前に受信していれば、その後程なく、サーバ装置１（b2）はクライアント装置２（s1）へpublish メッセージを送信し、pubackメッセージを受信するなど処理を実行する。publish メッセージに対してpubackメッセージを送信できていないことについてはセッションの切断によってリフレッシュされるなどすればよい。
【０１１５】
図２６は、図２５に示した状態から、セッションＧが再確立された場合の例を示す。なお、図２６の例では、サーバ装置１（b2）がセッションＧの切断前にpublish メッセージを受信できていない場合、又はそのタイミングでセッションＦについても切断しており、パブリッシャからのpublish メッセージが到達していない場合について説明する。サーバ装置１（b1, b2）間で同期処理が終了すると（Ｓ３０８）、サーバ装置１（b1）は、状態情報を記憶しているクライアント装置２（s1）の識別情報「s1」と、データベース３に記憶されている各クライアント装置２の接続先の情報（「connections 」）における識別情報「s1」とを照合する（Ｓ３０９）。サーバ装置１（b1）は、クライアント装置２（s1）について、接続先情報では自身が接続先ではないので（Ｓ３１０：ＮＯ）、クライアント装置２（s1）についての状態情報を削除する（Ｓ３１１）。
【０１１６】
サーバ装置１（b2）側でも、サーバ装置１（b1）とのセッションを再確立すると（Ｓ３０７）、同期処理を行なう（Ｓ３０８）。サーバ装置１（b2）は、状態情報を記憶しているクライアント装置２（s1）の識別情報「s1」と、データベース３に記憶されている各クライアント装置２の接続先情報（「connections 」）における識別情報「s1」とを照合する（Ｓ３０９）。サーバ装置１（b2）は、クライアント装置２（s1）について自身が接続先であると判断する（Ｓ３１０：ＹＥＳ）。サーバ装置１（b2）は、データベース３（「store 」及び「store_target_broker_user」テーブル）に記憶されている保存メッセージ及びブローカ経由の配信先情報に基づきpublish メッセージを読み出し（Ｓ３１３）パケットＩＤを採番して例えば（50）のタイミングでクライアント装置２（s1）へ送信する（Ｓ３１４）。その後（60）のタイミングでクライアント装置２（s1）から返されるpubackメッセージをサーバ装置（b2）が受信することで（Ｓ３１５）、保存メッセージ及び配信先情報は削除される（Ｓ３１６）。これにより、ブローカ・ブローカ間が切断されたとしてもサブスクライバ側へのQoS =1（「At least One」）でのメッセージの到達を達成できる。仮に、セッションＧが切断されたときにサーバ装置１（b2）側でpublish メッセージを受信できていて、これをサブスクライバであるクライアント装置２（s1）に送信済みであった場合、ブローカ・ブローカ間の切断によって保存された保存メッセージ及び配信先情報に基づいて別途新たなパケットＩＤで同一の内容のpublish メッセージが送信されることになる。しかしながら、QoS =1は最低１回受信であるから問題はない。
【０１１７】
図２７は、ブローカ間のセッションＧが再確立された後の処理の他の例を示す説明図である。図２７は、図２５に示した状態から、セッションＧが再確立されるがその前に、サーバ装置１（b2）とセッションを確立させていたサブスクライバであるクライアント装置２（s1）が、セッションＧの切断中にサーバ装置１（b1）へ接続先を変更する事態が発生した場合の例を示す。図２７において、クライアント装置２（s1）がサーバ装置１（b1）へセッション確立をリクエストし、これが承諾されるとサーバ装置１（b1）がデータベース３における接続先情報を識別情報「b1」に書き換える。この後同期処理が実行され、サーバ装置１（b1及びb2）間で接続情報が共有される。この場合、サーバ装置１（b1）は、状態情報を記憶しているクライアント装置２の識別情報「s1」と、データベース３に記憶されている各クライアント装置２の接続先情報（「connections 」）における識別情報「s1」とを照合し（Ｓ３０９）、接続先情報でも自身が接続先であると判断する（Ｓ３１０：ＹＥＳ）。サーバ装置１（b1）は、例えば（50）のタイミングでデータベース３（「store 」及び「store_target_broker_user」テーブル）に記憶されているサーバ装置１（b2）から送信されるはずであったpublish メッセージを読み出し（Ｓ３１３）、新たなパケットＩＤでクライアント装置２（s1）へpublish メッセージを送信する（Ｓ３１４）。データベース３に記憶されていた保存メッセージ及び配信先情報は、（60）のタイミングでクライアント装置２（s1）から送信されたpubackメッセージをサーバ装置１（b1）が受信することで（Ｓ３１５）、削除される（Ｓ３１６）。
【０１１８】
図２７で示す例においてサーバ装置１（b2）側では、サーバ装置１（b1）とのセッションを再確立すると（Ｓ３０７）、同期処理を行なう（Ｓ３０８）。サーバ装置１（b2）は、状態情報とデータベース３に記憶されている各クライアント装置２の接続先情報（「connections 」）における識別情報「s1」を照合し（Ｓ３０９）、自身が接続先でないと判断する（Ｓ３１０：ＮＯ）。サーバ装置１（b2）は、クライアント装置２（s1）についての状態情報を削除する（Ｓ３１１）。クライアント装置２（s1）向けの処理は上述のようにサーバ装置１（b1）側に任される。
【０１１９】
このように、MQTTモデルにおける到達保証のメッセージのやり取りの途中でブローカ間のセッションが切断された場合であっても、パブリッシャであるクライアント装置２からサブスクライバであるクライアント装置２までの経路におけるメッセージの到達保証をQoS =1とすることができる。
【０１２０】
次に図２４のフローチャートにおけるステップＳ３０５及びステップＳ３０６の間、セッションを再確立する間に新たにパブリッシャ又はパブリッシャ側の他のサーバ装置１からpublish メッセージを受信した場合の処理について説明する。図２８は、ブローカ間切断中のメッセージ処理手順の一例を示すフローチャートである。なお図２８のフローチャートに示す処理手順の内、図２０のフローチャートと共通する手順については同一のステップ番号を付して詳細な説明を省略する。
【０１２１】
ブローカであるサーバ装置１の制御部１０は、publish メッセージを受信して（Ｓ２０１）、このメッセージを他のサーバ装置１へ送信すると判断した場合（Ｓ２０３：ＹＥＳ）、送信先のサーバ装置１のいずれかとの間のセッションが切断しているか否かを判断する（ステップＳ２１１）。セッションが切断していないと判断された場合（Ｓ２１１）、制御部１０は他のサーバ装置１へpublish メッセージを送信し（Ｓ２０６）、他のサーバ装置１全てからpubackメッセージを受信したと判断してから（Ｓ２０７：ＹＥＳ）、送信元へpubackメッセージを返す（Ｓ２０８）。
【０１２２】
ステップＳ２１１にてセッションが切断していると判断した場合（Ｓ２１１：ＹＥＳ）、制御部１０は相手のサーバ装置１を通信接続先とするサブスクライバであるクライアント装置２についてのセッション情報をデータベース３（「keep_sub」テーブル）から参照する（ステップＳ２１２）。制御部１０は参照したセッション情報に基づき、抽出して記憶しているサブスクライバの状態情報を更新する（ステップＳ２１３）。例えば、図２４のフローチャートにおけるステップＳ３０３で記憶していたサブスクライバが、切断中にサブスクライブを停止していた場合には、これを反映し、以後のpublish メッセージの配信先から除外してもよくなる。制御部１０は、更新した状態情報に基づき、配信先をデータベース３としているサブスクライバであるクライアント装置２に関し、ステップＳ２０１で受信したpublish メッセージについてデータベース３（「store 」及び「store_target」テーブル）に保存メッセージ及び配信先情報を記憶する（ステップ２１４）。そして制御部１０は、切断中のメッセージの処理を終了する。
【０１２３】
切断から復帰した場合には、図２４のフローチャートのステップＳ３１０以降で、サブスクライバの接続先に応じて、いずれかのサーバ装置１が、データベース３からpublish メッセージを配信すればよい。
【０１２４】
図２８のフローチャートに示したように、サーバ装置１の制御部１０は、切断中（大抵の場合３秒から５秒の間）、publish メッセージを受信する都度、その間における各クライアント装置２の接続先の情報を自身が一時的に記憶している状態情報を適応させる。切断されたセッションの相手であるサーバ装置１を通信接続先とするサブスクライバのクライアント装置２がその切断中に、トピックのサブスクライブを止めたり（unsubscribe ）、新たにサブスクライブしたり、他のトピックをサブスクライブしたりした場合にも、状態情報を適応させて間違いなくメッセージを送信することが可能になる。
【０１２５】
ブローカのダウンを保証外とする場合、データベース３への情報の記憶は最低限としてあるから、QoS =1を保証しつつも送受信の速度が低減することが回避される。その代わり、ブローカであるサーバ装置１はいずれもダウンした場合には、自身に接続しているクライアント装置２の状態情報（online又はdatabase等）の一時記憶を全て失う。ブローカ間のセッションは起動時に新規に確立されるので、セッションに対応して記憶されている情報もダウン時に全て失われることになる。ステップＳ３０９等の照合ができないから、QoS =1のメッセージは失われることになる。
【０１２６】
（３）QoS =1、ブローカダウン保証
ブローカがダウンした場合もメッセージの到達を保証するという前提において、（２）同様に、経路である全てのセッションにてQoS が「１」に調停されるQoS =1が指定されたpublish メッセージのサブスクライバまでの到達について説明する。つまり（２）同様に、サブスクライバであるクライアント装置２が当該トピックを、QoS =1又は=2で指定している状態で、当該トピックについてパブリッシャがQoS =1を指定してpublish メッセージを送信するケースである。このメッセージについてトピック指定時に「０」を指定しているサブスクライバへの送信する場合の処理は（１）で述べたので説明を省略する。
【０１２７】
（３．１）正常運用時
ブローカがダウンした場合にメッセージの到達を保証する場合、ダウンしたことを自身で検知できないので、ダウンした場合の処理に切り替えるといったことができない。したがってダウン時に到達を保証するか否かは、ブローカ（サーバ装置１）のインスタンスが生成された時点で選択される。そしてダウンした場合にも到達保証を行なうことを選択して起動したブローカであるサーバ装置１は基本的に、自身にkeep接続しているクライアント装置２が１つでも存在する限り、パブリッシャであるクライアント装置又は他のサーバ装置１からpublish メッセージを受信する都度、データベース３（「store」及び「store_target」テーブル）に保存メッセージ及び配信先情報を保存する。そしてサーバ装置１は、publish メッセージに対するpubackメッセージを受信する都度、それらの保存メッセージ及び配信先情報を更新又は削除する処理を実行する（図７から図１２参照）。サーバ装置１は、自身にサブスクライバであるクライアント装置２が通信接続している場合には、publish メッセージを送信してからパブリッシャであるクライアント装置２側へpubackメッセージを送信する順序性を守る。同様にしてサーバ装置１は、他のサーバ装置１へ向けてpublish メッセージを送信する場合には、他のサーバ装置１全てからpubackメッセージを受信してからパブリッシャであるクライアント装置２側へpubackメッセージを送信する順序性を守る（図２０から図２２参照）。
【０１２８】
図２９は、ブローカダウンを保証するサーバ装置１における送信手順の一例を示すフローチャートである。なお図２９のフローチャートに示す処理手順は、図４のフローチャートに示した手順の内のステップＳ９の詳細に対応する。また図２９のフローチャートに示す処理手順の内、ブローカダウンを保証外とする際の図２０のフローチャートに示した処理手順と共通する手順については同一のステップ番号を付して詳細な説明を省略する。
【０１２９】
サーバ装置１の制御部１０は、ステップＳ２０１でpublish メッセージを受信した場合（Ｓ２０１：ＹＥＳ）、且つ、送信先に他のサーバ装置１が含まれないと判断された場合（ＳＳ２０３：ＮＯ）、ステップＳ２０２で抽出したトピックについての送信先に、keep接続を選択して通信接続しているサブスクライバであるクライアント装置２が存在するか否かを判断する（ステップＳ２２１）。keep接続を選択しているクライアント装置２が存在しないと判断された場合（Ｓ２２１：ＮＯ）、サーバ装置１の制御部１０は、自身に通信接続しているクライアント装置２へpublish メッセージを送信し（Ｓ２０４）、送信元へpubackメッセージを返す（Ｓ２０５）。ステップＳ２２１にて、keep接続を選択しているクライアント装置２が存在すると判断された場合（Ｓ２２１：ＹＥＳ）、セッションの切断が発生しているか否かに拘わらず、制御部１０は、publish メッセージ及びkeep接続である配信先の情報を保存メッセージ及び配信先情報としてデータベース３（「store 」及び「store_target」テーブル）に記憶してから（ステップＳ２２２）、対象となるクライアント装置２へpublish メッセージを送信する（Ｓ２０４）。
【０１３０】
そしてサーバ装置１の制御部１０は、pubackメッセージをpublish メッセージの送信元側へ送信した後（Ｓ２０５）、制御部１０は再度、ステップＳ２２１にて存在すると判断したか否かを判断する（ステップＳ２２３）。存在すると判断していないと判断された場合（Ｓ２２３：ＮＯ）、制御部１０は、そのまま１回のpublish メッセージの受信処理を終了する。
【０１３１】
ステップＳ２２３にて存在すると判断されていた場合（Ｓ２２３：ＹＥＳ）、制御部１０は、その存在するクライアント装置２、即ち抽出されたトピックを指定して自身にkeep接続しているクライアント装置２からpubackメッセージを受信したか否かを判断する（ステップＳ２２４）。受信していないと判断された場合（Ｓ２２４：ＮＯ）、制御部１０は受信したと判断するまでは、次のステップＳ２２５の処理は行なわない。pubackメッセージを受信したと判断された場合（Ｓ２２４：ＹＥＳ）、制御部１０は、ステップＳ２２２で記憶したpublish メッセージ及びkeep接続の送信先の情報をデータベース３から削除し（ステップＳ２２５）、publish メッセージの受信処理を終了する。
【０１３２】
ステップＳ２０３にて他のサーバ装置１が含まれると判断された場合（Ｓ２０３：ＹＥＳ）、制御部１０は、データベース３で共有しているセッション情報（「keep_sub」）から、ステップＳ２０２で抽出したトピックについて送信先の他のサーバ装置１からの送信先にkeep接続を選択して通信接続しているサブスクライバが存在するか否かを判断する（ステップＳ２２６）。ステップＳ２２６にて存在しないと判断された場合（Ｓ２２６：ＮＯ）、制御部１０はそのままpublish メッセージを他のサーバ装置１へ送信する（Ｓ２０６）。この場合制御部１０は、当該トピックをサブスクライブしている他のサーバ装置１全てからpubackメッセージを受信してから（Ｓ２０７：ＹＥＳ）、送信元へ向けてpubackメッセージを送信し（Ｓ２０８）、publish メッセージの受信処理を終了する。
【０１３３】
ステップＳ２２６にて存在すると判断された場合（Ｓ２２６：ＹＥＳ）、セッションの切断が発生しているか否かに拘わらず、制御部１０は、publish メッセージ（保存メッセージ）及びkeep接続の配信先情報をデータベース３（「store 」及び「store_target_broker 」テーブル）に記憶してから（ステップＳ２２７）、他のサーバ装置１へpublish メッセージを送信する（Ｓ２０６）。
【０１３４】
サーバ装置１の制御部１０は、当該トピックをサブスクライブしている他のサーバ装置１全てからpubackメッセージを受信してから（Ｓ２０７：ＹＥＳ）、送信元へ向けてpubackメッセージを送信した後（Ｓ２０８）、制御部１０は再度、ステップＳ２２６にて、keep接続を選択して通信接続しているサブスクライバであるクライアント装置２が存在すると判断したか否かを判断する（ステップＳ２２８）。存在しないと判断された場合（Ｓ２２８：ＮＯ）、制御部１０は、そのまま１回のpublish メッセージの受信処理を終了する。
【０１３５】
ステップＳ２２８にて存在すると判断された場合（Ｓ２２８：ＹＥＳ）、ステップＳ２２７で記憶したpublish メッセージ及びkeep接続の送信先の情報（保存メッセージ及び配信先情報）をデータベース３から削除し（ステップＳ２２９）、publish メッセージの受信処理を終了する。
【０１３６】
図２９のフローチャートに示した処理について、図面を参照して具体的に説明する。図３０から図３３は、QoS =1でブローカダウンを保証する際の処理を示す図である。図３０は、パブリッシャであるクライアント装置２（p1）、及び、サブスクライバであるクライアント装置２（s1, s2）と夫々セッションＡ，Ｂ，Ｃを確立しているサーバ装置１（b1）における処理を示している。サーバ装置１（b1）は、パブリッシャであるクライアント装置２（p1）からトピック「t1」について（10）のタイミングでpublish メッセージを受信すると（Ｓ２０１：ＹＥＳ）、トピック「t1」を指定してkeep接続を選択して通信接続しているクライアント装置２（s1）へ受信したpublish メッセージを（20）のタイミングで送信する（Ｓ２０４）。サーバ装置１（b1）はその前に、データベース３（「store 」及び「store_target」テーブル）に、メッセージの内容「a 」を含む保存メッセージと、識別情報「s1」を配信先とする配信先情報とを、publish メッセージを送信する際に採番したパケットＩＤと共に記憶する（Ｓ２２２）。サーバ装置１は、トピック「t1」のpublish メッセージについて、クライアント装置２（s2）もトピック「t1」を指定しているので（20）のタイミングで送信するが（Ｓ２０４）、クライアント装置２（s2）はkeep接続を選択していないので、識別情報「s2」の配信先情報はデータベース３に記憶されない。
【０１３７】
図３１は、図３０の状態よりも時間が経過した後の処理を示している。まずサーバ装置１は、クライアント装置２（s1, s2）へpublish メッセージを送信したことで次のタイミング（30）でパブリッシャであるクライアント装置２（p1）へpubackメッセージを送信する。これに前後して（例えばタイミング（35）にて）クライアント装置２（s1）からpubackメッセージが送信された場合、サーバ装置１は、パケットＩＤ及びpubackメッセージの送信元をキーとしてデータベース３（「store_target」テーブル）から配信先情報を検索する。keep接続を選択していないクライアント装置２（s2）についての検索結果はゼロ（空）であるが、keep接続を選択しているクライアント装置２（s1）については図３１に示すように検索される。サーバ装置１（b1）は、このpubackメッセージの受信を機に、レコードを削除する（Ｓ２２５）。サーバ装置１（b1）は、同一の保存メッセージ（「store 」テーブルにおける識別子：123 の情報）について配信先情報が空になったと判断された場合、参照されなくなった保存メッセージとしてこれをデータベース３（「store 」テーブル）から削除する（Ｓ２２５）。
【０１３８】
図３２は、トピック「t1」についてのパブリッシャであるクライアント装置２（p1）とセッションＥを確立しているブローカであるサーバ装置１（b1）における処理を示している。サーバ装置１（b1）は、トピック「t1」を指定トピックとするサブスクライバであるクライアント装置２（s1）が接続している他のサーバ装置１（b2）とメッセージを仲介する。サーバ装置１（b1）は、パブリッシャであるクライアント装置２（p1）からトピック「t1」について（10）のタイミングでpublish メッセージを受信する（Ｓ２０１：ＹＥＳ）。この場合、サーバ装置１（b1）は、サーバ装置１（b2）に対し、トピック「t1」を指定してkeep接続を選択して通信接続しているクライアント装置２（s1）が存在していると判断する（Ｓ２２６：ＹＥＳ）。サーバ装置１（b1）は、パブリッシャから受信したpublish メッセージを（20）のタイミングで送信するが（Ｓ２０６）、その前に、データベース３（「store 」及び「store_target_broker 」テーブル）へ、保存メッセージ及び配信先情報を記憶する（Ｓ２２７）。図３２例では、識別子「567 」の保存メッセージと、この保存メッセージの識別子「567 」と、送信時に使用されたパケットＩＤ「0x123 」を含むブローカ間の配信先情報（source_id=b1, target_id=b2, packet_id=0x123, store_id=567, already_sent=false ）が記憶されている。
【０１３９】
図３３は、図３２の状態よりも時間が経過した後の処理を示している。サーバ装置１（b2）は、サーバ装置１（b1）から送信されたpublish メッセージを、サブスクライバであるクライアント装置２（s1）へ送信したことで次のタイミング（40）にpubackメッセージを送信する。クライアント装置２（s1）から（45）のタイミングでpubackメッセージが送信されたとしてもこれを待つことなくサーバ装置１（b2）からpubackメッセージが送信される。サーバ装置１（b1）は、他のサーバ装置１全て（b2）からのpubackメッセージを受信すると（Ｓ２０７：ＹＥＳ）、パブリッシャであるクライアント装置２（p1）へ、例えば（50）のタイミングでpubackメッセージを送信する（Ｓ２０８）。サーバ装置１（b1）は、サーバ装置１（b2）からpubackメッセージを受信した場合、パケットＩＤ及びpubackメッセージの送信元（target_id=b2）をキーとしてデータベース３（「store_target_broker 」テーブル）から配信先情報を検索する。ステップＳ２２６にてkeep接続を選択して通信接続しているクライアント装置２（s1）が存在していると判断され（Ｓ２２８：ＹＥＳ）、配信先情報が検索されるはずであるから、サーバ装置１（b1）は、検索結果の配信先情報をデータベース３（「store_target_broker 」テーブル）から削除する（Ｓ２２９）。サーバ装置１（b1）は、同一の保存メッセージ（「store 」テーブルにおける識別子：567 ）について配信先情報が空になったと判断された場合、参照されなくなった保存メッセージをデータベース３（「store 」テーブル）から削除する（Ｓ２２９）。
【０１４０】
ブローカダウン時もメッセージの到達を保証することを選択して起動したブローカであるサーバ装置１（b1）は起動後、切断又はブローカダウンが発生していない間も図２９から図３３に示した処理を実行する。publish メッセージを受信する都度、データベース３への書き込みが実行され、pubackメッセージを受信する都度、削除が実行されるため、keep接続しているクライアント装置２が存在する場合にはメッセージの送受信にある程度の時間を要する。この点で、データベース３をＫＶＳ（Key-Value Store ）で構成し、作成、更新及び削除を全てイベントとして記憶する処理とすることで、データベース３への処理に要する時間を可及的に削減することが可能になる。
【０１４１】
（３．２）切断又はダウン発生時
セッションの切断が発生した場合は、サーバ装置１は夫々、その切断を検知することができ、図２４のフローチャートに示した処理と同一の処理を実行する。なおQoS =1でブローカダウン時にもメッセージの到達を保証する場合、上述したようにkeep接続しているクライアント装置２について、各サーバ装置１は正常運用時もデータベース３への記憶及び削除を繰り返し実行している。切断の原因が他のサーバ装置１のブローカダウンである場合、ブローカダウン時もメッセージを保証するケースでは、ネットワークコントローラの送信バッファにメッセージが残存しているか否かではなく、データベース３（「store_target_broker 」テーブル）に削除されていない保存メッセージ及び配信先情報が残存しているか否かを判断する。つまりサーバ装置１は、図２４のフローチャートにおけるステップＳ３０４において、送信バッファではなく、データベース３にメッセージが残存しているか否かを判断する。そして残存していると判断された場合（Ｓ３０４：ＹＥＳ）、制御部１０は、データベース３に残存していたメッセージを、本来であれば他のサーバ装置１とセッションを確立しているクライアント装置２へ送信されていたはずのメッセージ（保存メッセージ及びブローカ経由の配信先情報）としてデータベース３（「store_target_broker_user」テーブル）に保存（移動）する（Ｓ３０５）。
【０１４２】
ダウンしたブローカであるサーバ装置１は自身のダウンを検知することはできず、ネットワークコントローラの送信バッファにおける一時記憶情報も失われる。したがってダウンしたサーバ装置１は、図２４のフローチャートにおけるステップＳ３０４及びステップＳ３０５で示したような残存メッセージの退避保存処理はできない。またダウンしたサーバ装置１は、ダウン中に図２８のフローチャートにおけるステップＳ２１１からＳ２１４に示した切断中のメッセージの退避保存を行なうことはできない。したがって再起動したサーバ装置１は、他のサーバ装置１がデータベース３に記憶したメッセージを参照して、ダウン中に送信されたメッセージをクライアント装置２へ向けて送信する。
【０１４３】
図３４は、サーバ装置１の起動時の処理手順の一例を示すフローチャートである。サーバ装置１の制御部１０は、起動するとクライアント装置２及び他のサーバ装置１夫々とセッションを確立し（ステップＳ４０１）、確立したセッションにて他のサーバ装置１と同期処理を実行する（ステップＳ４０２）。
【０１４４】
サーバ装置１の制御部１０は、自身に接続しているとして一時記憶しているサブスクライバであるクライアント装置２の識別情報と、データベース３に記憶されている各クライアント装置２の接続先情報（「connections 」）とを照合する（ステップＳ４０３）。ステップＳ４０３の処理は、図２４のフローチャートに示したステップＳ３０８の処理と同様である。
【０１４５】
サーバ装置１の制御部１０は、ステップＳ４０３の照合の結果、自身に通信接続しており、状態情報がonlineであるクライアント装置２（複数存在する場合は夫々）について、データベース３に記憶されている接続先の情報中に基づき、接続先が自身であるか否かを判断する（ステップＳ４０４）。
【０１４６】
サーバ装置１の制御部１０は、自身でない（Ｓ４０４：ＮＯ）、制御部１０は、自身に接続しているクライアント装置２の状態情報の内、対象のサブスクライバであるクライアント装置２の情報を削除し（ステップＳ４０５）、起動時の処理を終了し、正常運用時の処理へ移行する（図４又は図２０等参照）。
【０１４７】
サーバ装置１の制御部１０は、ステップＳ４０４で自身であると判断した場合（Ｓ４０４：ＹＥＳ）、通信接続しているクライアント装置２に対し、他のサーバ装置１により、自身を経由して送信されるメッセージであったことを示す情報（ブローカ経由の配信先情報）を、データベース３（「store_target_broker_user」テーブル）から抽出する（ステップＳ４０６）。更に制御部１０は、通信接続しているサブスクライバであるクライアント装置２向けにデータベース３（「store 」及び「store_target」テーブル）に記憶しているメッセージを抽出する（ステップＳ４０７）。制御部１０は、ステップＳ４０６及びＳ４０７で抽出した情報に基づくpublish メッセージを、記憶した時刻の順にクライアント装置２へ送信する（ステップＳ４０８）。その後制御部１０は、送信先のクライアント装置２からpubackメッセージを受信し（ステップＳ４０９）、これを受信できた場合に、配信先情報、並びに保存してあったメッセージを削除する（ステップＳ４１０）。publish メッセージの送信により起動時の処理は終了する。なおステップＳ４０６及びＳ４０７で情報が抽出されない場合は勿論、ステップＳ４０８−Ｓ４１０の処理は実行されない。
【０１４８】
図３４のフローチャートに示した処理を、切断箇所別に説明する。
（３．２．１）パブリッシャ・ブローカ間
図２３の説明図に示したパブリッシャからサブスクライバまでの間のメッセージを、２つのブローカが仲介する場合に、パブリッシャ寄りに存在するブローカであるサーバ装置１（b1）がダウンする場合におけるパブリッシャ・ブローカ間のセッションについて説明する。この場合は、パブリッシャであるクライアント装置２（p1）は、改めて通信接続したブローカであるサーバ装置１（b1）へ新たなパケットＩＤにてpublish メッセージを再送することでQoS =1が実現可能である。
【０１４９】
なお、ブローカであるサーバ装置１（b1）は、パブリッシャであるクライアント装置２（p1）からpublish メッセージが送信され、これをサーバ装置１（b2）へ送信する前に、データベース３（「store_target_broker 」テーブル）にそのメッセージを記憶している。このときサーバ装置１（b1）は、クライアント装置２（p1）からpublish メッセージを受信したときに使用されていたパケットＩＤをデータベース３にイベントログとして記憶しておき、図２４及び図３４のフローチャートに示した処理手順で再起動後にやり取りを継続してもよい。サーバ装置１（b1）が、他のサーバ装置１全て（b2）からpubackメッセージを受信する前にダウンした場合、ダウンしている間にサーバ装置１（b2）が切断を検知し、データベース３（「store_target_broker 」テーブル）に記憶してあった配信先情報を、自身（b1）を経由して送信されるメッセージであったことを示す情報としてデータベース３（「store_target_broker_user」テーブル）へ移動できる。このときサーバ装置１（b1）は、データベース３への移動を契機にパブリッシャであるクライアント装置２（p1）へ向けてpubackメッセージを送信する。再確立後、サーバ装置１（b2）は、データベース３（「store_target_broker_user」テーブル）に記憶してある自身（b2）から送信されるメッセージであることを示す情報に基づき、クライアント装置２（s1）向けのpublish メッセージの送信を実行する。
【０１５０】
（３．２．２）ブローカ・サブスクライバ間
次に、サブスクライバ寄りに存在するブローカであるサーバ装置１（b2）がダウンするケースにおけるブローカ・サブスクライバ間のセッションについて説明する。図２３の説明図に示したセッションＦに対応する。図３５は、ブローカであるサーバ装置１（b2）がダウンした場合の処理を示す図である。詳細には、サーバ装置１（b2）が、クライアント装置２（s1）へpublish メッセージを送信し、pubackメッセージを受信する前にダウンした場合の例を示す。なお図３５の例では、サーバ装置１（b1）へのpubackメッセージが送信された後とする。
【０１５１】
図３５の例では、ブローカであるサーバ装置１（b1）へのpubackメッセージが送信された後にダウンによってセッションが切断される。サーバ装置１（b1、保証ありで起動）が、サーバ装置１（b2）に向けて（20）のタイミングでpublish メッセージ送信する前にデータベース３に記憶したメッセージ及び送信先（「store 」及び「store_target_broker 」テーブル）の情報は削除されている。サーバ装置１（b2）がダウン保証ありで再起動した場合に、（30）のタイミングでpublish メッセージを送信する前にデータベース３（「store 」及び「store_target」テーブル）に記憶していたメッセージ及び配信先情報に基づき、クライアント装置２（s1）へpublish メッセージが再送される（図１１同様）。このときパケットＩＤがデータベース３に記憶していた情報から参照されて送信される。クライアント装置２（s1）からそのパケットＩＤにてpubackメッセージが送信されることでデータベース３（「store 」及び「store_target」テーブル）からは情報が削除される。
【０１５２】
（３．２．３）ブローカ・ブローカ間
次に、サブスクライバ寄りに存在するブローカであるサーバ装置１（b2）がダウンするケースにおけるブローカ間のセッションについて説明する。図３６は、ブローカであるサーバ装置１（b2）がダウンした場合の処理を示す図である。詳細には、サーバ装置１（b2）が、ブローカであるサーバ装置１（b1）からのpublish メッセージを受信する前後、クライアント装置２（s1）へpublish メッセージへの送信を行なう前にダウンした場合の例を示す。
【０１５３】
図３６の例では、サーバ装置１（b1、保証ありで起動）がサーバ装置１（b2）に向けて（20）のタイミングでpublish メッセージを送信する前に、データベース３に記憶したメッセージ及び送信先（「store 」及び「store_target_broker 」テーブル）の情報は残っている。サーバ装置１（b1）は、サーバ装置１（b2）のダウンによるセッションＧが切断されたことを検知すると（図２４のステップＳ３０１）、サーバ装置１（b2）とセッションを確立しているクライアント装置２（s1）へ送信されていたはずのメッセージとしてデータベース３（「store_target_broker_user」テーブル）にブローカ経由の配信先情報を保存（移動）する（Ｓ３０５）。そしてサーバ装置１（b1）は、データベース３に保存したことによってパブリッシャであるクライアント装置２（p1）へpuback メッセージを送信する（Ｓ３０６）。
【０１５４】
図３７は、図３６に示した状態の後、サーバ装置１（b2）が起動した後に行なわれる処理の例を示す図である。サーバ装置１（b1, b2）は夫々相互にセッションの確立、同期処理及び照合等の処理を行なう（図２４のＳ３０７からＳ３０９、図３４のＳ４０１からＳ４０３）。再起動したサーバ装置１（b2）は、クライアント装置２（s1）について、接続先は自身であると判断する（Ｓ４０４：ＹＥＳ）。サーバ装置１（b2）は、接続先を自身とするクライアント装置２（s1）へ送信されていたはずのメッセージ（ブローカ経由の配信先情報）をデータベース３（「store_target_broker_user」テーブル）から抽出し（Ｓ４０６）、新たなパケットＩＤ（「0x133 」）を用いてタイミング（50）で送信する（Ｓ４０８）。このときサーバ装置１（b2）によって再度、データベース３（「store 」及び「store_target」テーブル）に保存メッセージ及び配信先情報（user_id=s1, packet_id=0x133, store_id=789, already_sent=false, qos=1）が記憶される。その後（60）のタイミングにてクライアント装置２（s1）からpubackメッセージが送信され、サーバ装置１（b2）がこれを受信する（Ｓ４０９）ことで、この保存メッセージ及び配信先情報が削除されている（Ｓ４１０）。
【０１５５】
このようにして、ブローカであるサーバ装置１がセッションの切断のみならずダウンした場合であっても、パブリッシャからQoS =1を指定して送信されたメッセージについて、サブスクライバまでの到達を、QoS =1（「At least Once 」（最低１回、１回以上届く））で保証することが可能である。
【０１５６】
（４）QoS =2、ブローカダウン保証外の動作
次に、ブローカがダウンした場合にメッセージの到達を保証しないという前提において、パブリッシャであるクライアント装置２からQoS =2を指定してpublish メッセージが送信される場合の処理について説明する。なお以下の説明では、当該メッセージのトピックを指定しているサブスクライバであるクライアント装置２が、トピック指定時にQoS として「２」を指定している場合の当該サブスクライバまでのメッセージの到達について説明する。なお、同一のメッセージのサブスクライバであって、トピック指定時に「０」を指定しているサブスクライバへのメッセージ送信は（１）で述べたようにpublish メッセージを１回送信するのみで処理が終了するので説明を省略する。また、トピック指定時に「１」を指定しているサブスクライバへのメッセージの送信は（２）で述べたpubackメッセージの順序性をpubrecメッセージに読み替えた内容に基づき行なわれる。つまり原則的に、他のサーバ装置１全てからpubackメッセージを受信するまで、送信元へpubrecメッセージを返さないという制御が行なわれる。
【０１５７】
（４．１）正常運用時
QoS =2で送信されるメッセージを保証する場合、ブローカであるサーバ装置１は、パケットＩＤ対応情報（pidmap）を記憶して利用する。図１に示したように通信システム１００では、複数のブローカ（大抵は１又は２台）がメッセージの配信を仲介する。パブリッシャであるクライアント装置２が接続しているブローカと、サブスクライバであるクライアント装置２が接続しているブローカとが異なる場合、即ちメッセージの送受信に２台以上のブローカが存在する場合には、メッセージはこのブローカ間のセッションを経由する。図３に示したようにサーバ装置１はMQTTモデルに準拠し、セッション毎に、パケットＩＤをキーとしてメッセージをやり取りする。本開示のサーバ装置１は、自身が確立するセッションに関し、同一のメッセージの送信のために異なるセッション間で使用されたパケットＩＤの対応関係をパケットＩＤ対応情報（pidmap）として記憶する。正常時からパケットＩＤ対応情報を記憶しておくことにより、後述するように、メッセージのやり取りの中途でセッションが切断した場合、又はサーバがダウンした場合であっても直前の状態に復帰させることが可能になる。
【０１５８】
図３８は、QoS =2におけるパケットＩＤ対応情報の説明図である。なお図３８の説明図では、パブリッシャであるクライアント装置２と該パブリッシャから送信されるメッセージのトピックを指定トピックとしているサブスクライバであるクライアント装置２との間に、２つのブローカが介在する場合の接続構成にて各サーバ装置１で記憶される情報の例を示している。図３８では、クライアント装置２（p1）がパブリッシャとしてサーバ装置１（b1）に通信接続し（セッションＪ）、同じサーバ装置１（b1）にクライアント装置２（s2）がサブスクライバとして通信接続している（セッションＭ）。クライアント装置２（s1）は、サブスクライバとしてサーバ装置１（b2）に通信接続している（セッションＫ）。２つのブローカであるサーバ装置１（b1, b2）間も、通信接続されている（セッションＬ）。図３８の例においてクライアント装置２（p1）から送信されるメッセージは、セッションＪ及びセッションＭを経由してクライアント装置２（s2）へ到達し、セッションＪ、セッションＬ及びセッションＫを経由してクライアント装置２（s1）へ到達する。
【０１５９】
サーバ装置１は夫々、３種類のパケットＩＤ対応情報を一時記憶部１３に記憶している。３種類のパケットＩＤ対応情報は第１に、クライアント装置２から自身であるサーバ装置１へのメッセージにおけるパケットＩＤと（userからの受信の意味で「u 」）、自身であるサーバ装置１からクライアント装置２へのメッセージにおけるパケットＩＤと（userへの送信の意味で「u 」）の対応関係（pid_map_u2u ）を含む。第２に、クライアント装置２から自身であるサーバ装置１へのメッセージにおけるパケットＩＤと（userからの受信の意味で「u 」）、自身であるサーバ装置１から他のサーバ装置１へのメッセージにおけるパケットＩＤと（brokerへの送信の意味で「b 」）の対応関係（pid_map_u2b ）を含む。第３に、他のサーバ装置１から自身であるサーバ装置１へのメッセージにおけるパケットＩＤと（brokerからの受信の意味で「b 」）、自身であるサーバ装置１からクライアント装置２へのメッセージにおけるパケットＩＤと（userへの送信の意味で「u 」）の対応関係（pid_map_b2u ）を含む。夫々のパケットＩＤ対応情報は、自身へのメッセージの送信者の識別情報（[source_user(broker)_id]）、自身からのメッセージの受信者の識別情報（[target_user(broker)_id]）、前記送信者からのパケットＩＤ（[source_pid]、図中では[s_pid]で示す)、前記受信者向けのパケットＩＤ（[target_pid]、図中では[t_pid]で示す）、メッセージの送信の完了を示す論理値（[sent]）を含む。
【０１６０】
図３８に示す接続構成の場合、ブローカであるサーバ装置１（b1）は、パブリッシャであるクライアント装置２（p1）から送信されるpublish メッセージについて３種類のパケットＩＤ対応情報の内、次の２つのパケットＩＤ対応情報を用いる。１つは、クライアント装置２（p1）からのメッセージのパケットＩＤと、自身に通信接続しているサブスクライバであるクライアント装置２（s2）へのメッセージのパケットＩＤとの対応関係のためのパケットＩＤ対応情報（pid_map_u2u ）である。１つは、クライアント装置２（p1）からのメッセージのパケットＩＤと、自身と通信接続している他のブローカであるサーバ装置１（b2）へのメッセージのパケットＩＤとの対応関係のためのパケットＩＤ対応情報（pid_map_u2b ）である。図３８に示す例では、サーバ装置１（b1）は、パブリッシャであるクライアント装置２（p1）からのパケットＩＤと、サブスクライバであるクライアント装置２（s2）へのメッセージのパケットＩＤとの対応関係のための第１のパケットＩＤ対応情報（pid_map_u2u ）（source_user_id=p1, target_user_id=s2）を用いる。同様にして、サーバ装置１（b1）は、パブリッシャであるクライアント装置２（p1）からのパケットＩＤと、他のブローカであるサーバ装置１（b2）へのメッセージのパケットＩＤとの対応関係のための第２のパケットＩＤ対応情報（pid_map_u2b ）（source_user_id=p1, target_broker_id=b2）を用いる。
【０１６１】
同様にして図３８に示す接続構成では、サーバ装置１（b2）は、他のサーバ装置１（b1）からのメッセージのパケットＩＤと、自身に通信接続しているサブスクライバであるクライアント装置２（s1）へのメッセージのパケットＩＤとの対応関係のためのパケットＩＤ対応情報（pid_map_b2u ）（source_broker_id=b1, target_user_id=s1）を用いる。
【０１６２】
図３９は、パケットＩＤ対応情報を用いたメッセージの処理手順の一例を示すフローチャートである。なお図３９のフローチャートに示す処理手順は、図４のフローチャートに示した手順の内のステップＳ９の詳細に対応する。
【０１６３】
サーバ装置１の制御部１０は、パブリッシャとして通信接続を確立している１又は複数のクライアント装置２から、又は他のサーバ装置１からpublish メッセージを受信したか否かを判断する（ステップＳ５０１）。受信していないと判断された場合（Ｓ５０１：ＹＥＳ）、制御部１０は処理をステップＳ５０１へ戻す。
【０１６４】
制御部１０は、受信したと判断した場合（Ｓ５０１：ＹＥＳ）、受信したpublish メッセージのパケットＩＤを特定する（ステップＳ５０２）。制御部１０は、受信したpublish メッセージのトピックを抽出し（ステップＳ５０３）、抽出されたトピックについての送信先に他のサーバ装置１が含まれるか否かを判断する（ステップＳ５０４）。
【０１６５】
ステップＳ５０３にて他のサーバ装置１が含まれないと判断された場合（Ｓ５０４：ＮＯ）、制御部１０は、ステップＳ５０１で受信したpublish メッセージについて、抽出されたトピックを指定して自身に通信接続しているサブスクライバであるクライアント装置２を受信者とするレコードを、記憶しているパケットＩＤ対応情報（pid_map_u2u ）から検索できたか否か判断する（ステップＳ５０５）。ステップＳ５０５にて制御部１０は、送信者（[source_user(broker)_id]）、受信者（[target_user(broker)_id]）及びステップＳ５０２で特定したパケットＩＤ（[source_pid]）でレコードを検索する。
【０１６６】
ステップＳ５０５で検索できなかったと判断された場合（Ｓ５０５：ＮＯ）、新規のメッセージであるから制御部１０は、受信者とのセッションにおけるパケットＩＤを採番し（ステップＳ５０６）、レコードを作成して記憶する（ステップＳ５０７）。制御部１０は、ステップＳ５０６で採番したパケットＩＤを使用して、サブスクライバであるクライアント装置２へ向けてステップＳ５０１で受信したpublish メッセージを送信する（ステップＳ５０８）。
【０１６７】
検索できたと判断された場合（Ｓ５０５：ＹＥＳ）、制御部１０は、レコードにおけるメッセージの送信完了が完了を示しているか否かを判断する（ステップＳ５０９）。完了していないと判断された場合（Ｓ５０９：ＮＯ）、publish メッセージを再送する（ステップＳ５０８）。なおステップＳ５０８において、検索されたレコードに受信者向けのパケットＩＤが存在する場合は、そのパケットＩＤを使用して送信し、存在しない場合はここでパケットＩＤを採番して送信するとよい。
【０１６８】
送信が完了していると判断された場合（Ｓ５０９：ＹＥＳ）、制御部１０は送信処理を省略して次のステップＳ５１０）へ処理を進める。
【０１６９】
なおステップＳ５０８において制御部１０は、送信先に、keep接続を選択しており且つセッションが切断中であるクライアント装置２が存在する場合には、送信先をデータベース３とする。送信先をデータベース３とする場合は、ステップＳ５０５のパケットＩＤは採番できないので、パケットＩＤなしでパケットＩＤ対応情報を記憶するとよい（Ｓ５０７）。
【０１７０】
続いて制御部１０は、受信したpublish メッセージの送信元（パブリッシャ又は他のサーバ装置１）へpubrecメッセージを返す（ステップＳ５１０）。制御部１０は、publish メッセージの受信者からpubrecメッセージを受信したか否かを判断する（ステップＳ５１１）。受信していないと判断された場合（Ｓ５１１：ＮＯ）、制御部１０は処理をステップＳ５１１へ戻し、受信したと判断されるまで待機する。受信したと判断された場合（Ｓ５１１：ＹＥＳ）、制御部１０は、パケットＩＤ対応情報のレコードをpubrecメッセージの送信元を受信者の識別情報（[target_user(broker)_id]）及びpubrecメッセージのパケットＩＤ（[target_pid]）で検索し、検索されたレコードについて、メッセージが送信完了であるとして更新する（ステップＳ５１２）。
【０１７１】
次に制御部１０は、pubrelメッセージをpublish メッセージの送信者から受信したか否かを判断する（ステップＳ５１３）。受信していないと判断された場合（Ｓ５１３：ＮＯ）、制御部１０は処理をステップＳ５１３へ戻し、受信したと判断されるまで待機する。受信したと判断された場合（Ｓ５１３：ＹＥＳ）、制御部１０は、パケットＩＤ対応情報のレコードを送信者のpubrelメッセージの送信者の識別情報（[source_user(broker)_id]）及びpubrelメッセージのパケットＩＤ（[source_pid]）で検索し、検索されたレコードを削除し（ステップＳ５１４）、１つのpublish メッセージの配信処理を終了する。
【０１７２】
ステップＳ５０４にて他のサーバ装置１が含まれると判断された場合（Ｓ５０４：ＹＥＳ）、制御部１０は、他のサーバ装置１に向けて、上述のステップＳ５０５からＳ５０９に示した処理と同様の処理Ｓ５１５からＳ５１９を、記憶しているパケットＩＤ対応情報（pid_map_u2b ）に対して行なう。なお、ステップＳ５１８において制御部１０は、他のサーバ装置１以外に、抽出されたトピックを指定して自身に通信接続しているサブスクライバであるクライアント装置２へ送信する場合には、同様にしてpublish メッセージを送信する（Ｓ５１８）。
【０１７３】
他のサーバ装置が送信先に含まれる場合、制御部１０はステップＳ５１８の後に、他のサーバ装置１全てからpubrecメッセージを受信するまで、pubrecメッセージを受信したか否か判断する（ステップＳ５２０）。受信していないと判断された場合（Ｓ５２０：ＮＯ）、制御部１０は処理をステップＳ５２０へ戻し、次のステップＳ５２１には進まない。受信したと判断された場合（Ｓ５２０：ＹＥＳ）、制御部１０は、パケットＩＤ対応情報のレコードをpubrecメッセージの送信元を受信者の識別情報（[target_user(broker)_id]）及びpubrecメッセージのパケットＩＤ（[target_pid]）で検索し、検索されたレコードについて、メッセージが送信完了であるとして更新する（ステップＳ５２１）。そして他のサーバ装置１全てからpubrecメッセージを受信したか否かを判断する（ステップＳ５２２）。全てから受信していないと判断された場合（Ｓ５２２：ＮＯ）、制御部１０は処理をステップＳ５２０へ戻し、他のpubrecメッセージを受信するまで次のステップＳ５２３の処理は行なわない。ステップＳ５２２にて、他のサーバ装置１全てからpubrecメッセージを受信したと判断された場合（Ｓ５２２：ＹＥＳ）、制御部１０は、自身に通信接続しているクライアント装置２からpubrecメッセージを受信していなくとも、この場合はステップＳ５２３へ処理を進め、クライアント装置２からのpubrecメッセージについては個別に処理する。
【０１７４】
ステップＳ５２２にて他のサーバ装置１全てからpubrecメッセージを受信したと判断された場合（Ｓ５２２：ＹＥＳ）、制御部１０は、受信したpublish メッセージの送信元（パブリッシャ又は他のサーバ装置１）へpubrecメッセージを返す（ステップＳ５２３）。続けて制御部１０は、pubrelメッセージをpublish メッセージの送信者から受信したか否かを判断する（ステップＳ５２４）。受信していないと判断された場合（Ｓ５２４：ＮＯ）、制御部１０は処理をステップＳ５２４へ戻し、受信したと判断されるまで待機する。受信したと判断された場合（Ｓ５２４：ＹＥＳ）、制御部１０は、パケットＩＤ対応情報のレコードを送信者のpubrelメッセージの送信者の識別情報（[source_user(broker)_id]）及びpubrelメッセージのパケットＩＤ（[source_pid]）で検索し、検索されたレコードを削除し（ステップＳ５２５）、１つのpublish メッセージの配信処理を終了する。
【０１７５】
図４０から図４２を参照して、図３９のフローチャートに示した処理手順を具体的に説明する。図４０から図４２は、パケットＩＤ対応情報の内容例を示す図である。まず図４０は、パブリッシャであるクライアント装置２（p1）がpublish メッセージを送信してから、２つのブローカであるサーバ装置１（b1, b2）を経由してサブスクライバであるクライアント装置２（s1）へpublish メッセージが送信される時点までのパケットＩＤ対応情報（「pidmap」）を示す。図４０に示すように、サーバ装置１（b1）は、パブリッシャであるクライアント装置２（p1）からタイミング（10）でpublish メッセージを受信すると（Ｓ５０１：ＹＥＳ）、クライアント装置２（s2）とのセッションにおいてパケットＩＤ「0x126 」を採番する（Ｓ５１６）。サーバ装置１（b1）は、パケットＩＤ対応情報（pid_map_u2u ）に識別情報「p1」の送信者からのパケットＩＤ「0x112 」と識別情報「s2」の受信者へのパケットＩＤ「0x126 」の対応関係を示すレコード（source_user_id=p1, target_user_id=s2, s_pid=0x112, t_pid=0x126, sent=false）を作成して記憶する（Ｓ５１７）。制御部１０は、採番したパケットＩＤ「0x126 」を用いて（20）のタイミングで識別情報「s2」の受信者へpublish メッセージを送信する（Ｓ５１８）。（30）のタイミングで識別情報「s2」の受信者からは、pubrecメッセージが送信されるので、サーバ装置１（b1）はこれを受信し（Ｓ５２０）、送信完了の論理値（sentの初期値は「false 」）を「true」で更新する（Ｓ５２２）。
【０１７６】
サーバ装置１（b1）は、他のサーバ装置１（b2）へもpublish メッセージを送信すべくサーバ装置１（b2）とのセッションにおいてパケットＩＤ「0x125 」を採番する（Ｓ５１６、Ｓ５０６）。サーバ装置１（b1）は、パケットＩＤ対応情報（pid_map_u2b ）に識別情報「p1」の送信者からのパケットＩＤ「0x112 」と識別情報「b2」の受信者へのパケットＩＤ「0x125 」の対応関係のレコード（source_user_id=p1, target_broker_id=b2, s_pid=0x112, t_pid=0x125, sent=false）を記憶する（Ｓ５１７）。制御部１０は、採番したパケットＩＤ「0x125 」を用いて（20）のタイミングでサーバ装置１（b2）へpublish メッセージを送信する（Ｓ５１８）。図４０に示すタイミングでは、識別情報「b2」の受信者からのpubrecメッセージは未受信であるから、対応するレコードにおける送信完了の論理値（sent）は初期値「false 」のままである。
【０１７７】
図４０に示す例では、サーバ装置１（b2）においてもサブスクライバであるクライアント装置２（s1）へpublish メッセージを送信するに際し、パケットＩＤ「0x134 」を採番する（Ｓ５０６）。制御部１０は、パケットＩＤ対応情報（pid_map_b2u ）に識別情報「b1」の送信者からのパケットＩＤ「0x125 」と、識別情報「s1」の受信者へのパケットＩＤ「0x134 」との対応関係を示すレコード（source_broker_id=b1, target_user_id=s1, x_pid=0x125, t_pid=0x134, sent=false）を作成して記憶する（Ｓ５０７）。サーバ装置１（b2）の制御部１０は、採番したパケットＩＤ「Z 」を用いて（30）のタイミングでクライアント装置２（s1）へpublish メッセージを送信する（Ｓ５０８）。
【０１７８】
図４１は、図４０の後、サーバ装置１（b2）からpubrecメッセージが送信される時点（タイミング（40））までのパケットＩＤ対応情報（「pidmap」）を示す。図４１では、サーバ装置１（b2）は、（30）のタイミングでクライアント装置２（s1）へpublish メッセージを送信すると、順序性を守ってサーバ装置１（b1）へpubrecメッセージを送信する（Ｓ５１０）。これにより、サーバ装置１（b1）は、自身が送信したpublish メッセージについて、受信者であるサーバ装置１（b2）からpubrecメッセージを受信するので（Ｓ５２０）、対応するパケットＩＤ対応情報（pid_map_u2b ）のレコードの送信完了の論理値（sent）を「true」に更新している（Ｓ５２１）。サーバ装置１（b1）は、他のサーバ装置１全てからpubrecメッセージを受信するので（Ｓ５２２：ＹＥＳ）、この後、パブリッシャであるクライアント装置２（p1）へ向けて、pubrecメッセージを送信する。
【０１７９】
図４１の例では、サーバ装置１（b2）においても、受信者であるクライアント装置２（s1）からpubrecメッセージを受信したので、対応するパケットＩＤ対応情報（pid_map_b2u ）のレコードの送信完了の論理値（sent）を「true」に更新している（Ｓ５１２）。
【０１８０】
図４２は、パブリッシャであるクライアント装置２（p1）からのpublish メッセージの配信処理が完了した後のパケットＩＤ対応情報（「pidmap」）を示す。サーバ装置１（b1）は、（40）のタイミングで受信したpubrecメッセージにより、他のサーバ装置１全てからpubrecメッセージを受信したと判断するので（Ｓ５２２：ＹＥＳ）、（50）のタイミングで、パブリッシャであるクライアント装置２（p1）へ向けて、pubrecメッセージを送信する（Ｓ５２３）。
【０１８１】
パブリッシャであるクライアント装置２（p1）は、パケットＩＤ「0x112 」について受信者であるサーバ装置１（b1）からpubrecメッセージを受信するので、pubrelメッセージを送信する。サーバ装置１（b1）は、pubrelメッセージを受信したので（Ｓ５２４：ＹＥＳ）、送信者の識別情報「p1」及びpubrelメッセージのパケットＩＤ「0x112 」でパケットＩＤ対応情報を検索し、「pid_map_u2u 」及び「pid_map_u2b 」にて合致する２つレコードをいずれも削除し（Ｓ５２５）、配信処理を終了する。
【０１８２】
サーバ装置１（b1）はネットワークコントローラの動作により、サーバ装置１（b2）を受信者とするパケットＩＤ「0x125 」のメッセージについて、pubrecメッセージを受信すると、pubrelメッセージを送信する。これによりサーバ装置１（b2）でも、pubrelメッセージを受信したので（Ｓ５１３：ＹＥＳ）、送信者の識別情報「b1」及びpubrelメッセージのパケットＩＤ「0x125 」でパケットＩＤ対応情報を検索し、「pid_map_b2u 」にて合致する２つレコードをいずれも削除し（Ｓ５１４）、配信処理を終了する。
【０１８３】
上述の処理に示したように、QoS =2に調停された場合もQoS =1に調停された場合と同様に、各サーバ装置１における処理の順序性は保たれ、それに加えてパケットＩＤ対応情報を各自記憶される。QoS =2の場合、セッションが切断されたことで再接続時に同一のパケットＩＤを使用してpublish メッセージが再送されるが、各サーバ装置１は、同一の送信者から同一のパケットＩＤを使用したpublish メッセージについて、受信者からpubrecメッセージを受信しているケースでは再送を行なわない。これにより、パブリッシャからサブスクライバまでのメッセージが、異なるセッションを跨ぐケースでも、メッセージの到達をQoS =2で保証することが可能である。
【０１８４】
（４．２）切断発生時
ブローカがダウンした場合は保証しないという前提で、パブリッシャであるクライアント装置２とサーバ装置１との間、２つのサーバ装置１の間、サーバ装置１とサブスクライバであるクライアント装置２との間のセッションがメッセージのやり取り途中で切断した場合について説明する。なお以下の説明は、図３８に示した構成におけるセッションＪからセッションＭの内のいずれか１つ又は複数が切断された例を挙げて説明する。
【０１８５】
（４．２．１）パブリッシャ・ブローカ間
パブリッシャであるクライアント装置２から、QoS =2で調停されたサブスクライバへのデータの送信に関し、パブリッシャとブローカとの間のセッションが切断されるケースについて考える。このケースは、図４０に示したパブリッシャであるクライアント装置２（p1）からpublish メッセージが送信された後、サーバ装置１（b1）からpubrecメッセージが送信される前に、クライアント装置２（p1）とサーバ装置１（b1）の間のセッションＪが切断されるケースである。
【０１８６】
このケースでは、パブリッシャであるクライアント装置２（p1）は、送信したpublish メッセージに対するpubrecメッセージが返されるまで、そのpublish メッセージを送信バッファに一時記憶したままとする（図３）。セッションＪが再度確立された場合、クライアント装置２（p1）は、送信バッファに一時記憶しているpublish メッセージを再度セッションＪにおいて、同一パケットＩＤを用いて接続先のサーバ装置１（b1）へ送信する。サブスクライバへのメッセージの到達保証がQoS =2に調停されている場合、この２回目以降の同一のpublish メッセージを起源とするpublish メッセージが、サブスクライバであるクライアント装置２で重複して受信処理されることを回避しなければならない。
【０１８７】
本実施の形態におけるサーバ装置１の処理により、図４０の状態でセッションＪが切断されるケースでも、まず、サブスクライバであるクライアント装置２へ（s1）のメッセージ到達を「Exactly once」（正確に１回、ちょうど１回だけ届く）（QoS =2）とすることができる。サーバ装置１（b1）は、切断される前にパブリッシャであるクライアント装置２（p1）から受信したpublish メッセージについて、クライアント装置２（s1）が通信接続している他のサーバ装置１（b2）へのpublish メッセージの送信を完了している場合、パケットＩＤ対応情報のレコード（pid_map_u2b）を一時記憶している。したがって、再送されたpublish メッセージをパブリッシャから受信した場合、サーバ装置１（b1）は、同一の送信者からの同一のパケットＩＤを含み、他のサーバ装置１（b2）を受信者とするレコードを検索できる（source_user_id=p1, source_pid=0x112, target_broker_id=b2）。
【０１８８】
レコードが検索できた場合、送信先のサーバ装置１（b2）から、サーバ装置１（b1）へpubrecメッセージが送信される前、即ち、その先に通信接続しているクライアント装置２（s1）へのpublish メッセージの送信前であれば、検索されたレコードにおける送信完了の論理値（sent）は「false 」である。この場合、サーバ装置１（b1）は、検索されたレコードに含まれる受信者（target_broker_id=b2 ）へのパケットＩＤ（target_pid=0x125）を用いてpublish メッセージを再送する。サーバ装置１（b1）からのpublish メッセージの再送を受けたサーバ装置１（b2）は、通信接続しているクライアント装置２（s1）からのpubrecメッセージを受信していない場合、publish メッセージを同様にして再送する。セッションＫにおけるMQTTモデルによって、クライアント装置２（s1）は、pubrelメッセージを受信するまでは、再送されたpublish メッセージを受信しても受信処理せずに破棄するから、重複して受信処理を行なうことはない。
【０１８９】
サーバ装置１（b2）は、通信接続しているクライアント装置２（s1）へ、セッションＪの切断前にパブリッシャから送信されたメッセージに基づくpublish メッセージを送信済みである場合、pubrecメッセージをサーバ装置１（b1）へ返しているか、返そうとしている。サーバ装置１（b1）はほどなく、このpubrecメッセージを受信し、検索されたレコードにおける送信完了の論理値（sent）は「true」に更新されている。パブリッシャからpublish メッセージの再送を受けた時点で、検索されたレコードの送信完了の論理値（sent）が「true」である場合、サーバ装置１（b1）はサーバ装置１（b2）へ向けてpublish メッセージを再送しない。このように、クライアント装置２（s1）へ、セッションＪの切断前にパブリッシャから送信されたpublish メッセージに基づくpublish メッセージが送信済みである場合、サーバ装置１（b2）へも同一のpublish メッセージに基づくpublish メッセージの再送はなされない。クライアント装置２（s1）へ重複してメッセージが到達することはない。
【０１９０】
パブリッシャからpublish メッセージの再送を受けた時点で、検索されたレコードの送信完了の論理値（sent）が「false 」である場合、サーバ装置１（b1）はサーバ装置１（b2）へ向けてpublish メッセージを再送するが、サーバ装置１（b2）では、同一パケットＩＤによるpublish メッセージを受信済みで処理しているので、この再送されたpublish メッセージはMQTTモデルに基づくセッション毎の到達保証により、破棄される。クライアント装置２（s1）へ重複してメッセージが到達することはない。
【０１９１】
サーバ装置１（b1）は、切断される前にパブリッシャであるクライアント装置２（p1）から受信したpublish メッセージについて、識別情報「s1」のクライアント装置２が通信接続している他のサーバ装置１（b2）へのpublish メッセージの送信を行なう際に、他のサーバ装置１（b2）とのセッションＬが切断されている場合、メッセージ及びその配信先をデータベース３（「store 」及び「store_target_broker」テーブル）として記憶する（後述）。このときサーバ装置１（b1）は、受信者を送信先であるはずであった他のサーバ装置１の識別情報「b2」、受信者へのパケットＩＤを「NULL」とし、送信完了の論理値を「true」とするパケットＩＤ対応情報（pid_map_u2b ）のレコードを作成して記憶しておく。この場合、他のサーバ装置１（b2）側で、データベース３（「store 」及び「store_target_broker」テーブル）に記憶されている自身宛のメッセージが保存されていることを認識でき、受信処理がなされるはずである。セッションＪが切断された後、パブリッシャからメッセージの再送を受けたとしても、同一の送信者からの同一のパケットＩＤを含み、他のサーバ装置１（b2）を受信者とするレコードを検索でき、しかも送信完了が「true」であるから、セッションＬが再接続されたとしても再送を行なわれることが回避される。これにより、メッセージが重複して到達することはない。
【０１９２】
図４０の状態でセッションＪが切断された場合に、サーバ装置１（b1）に直接的に通信接続しているサブスクライバであるクライアント装置２（s2）へのメッセージ到達についても「Exactly once」（QoS =2）とすることができる。
【０１９３】
サーバ装置１（b1）は、切断される前にパブリッシャであるクライアント装置２（p1）から受信したpublish メッセージについて、クライアント装置２（s2）へのpublish メッセージの送信を完了している場合、パケットＩＤ対応情報のレコード（pid_map_u2u ）を一時記憶している。したがって、再送されたpublish メッセージをパブリッシャから受信した場合、サーバ装置１（b1）は、同一の送信者からの同一のパケットＩＤを含み、クライアント装置２（s2）を受信者とするレコードを検索できる（source_user_id=p1, source_pid=0x112, target_user_id=s2）。
【０１９４】
レコードが検索できた場合、送信先のクライアント装置２（s2）から、サーバ装置１（b1）へpubrecメッセージが送信される前であれば、検索されたレコードにおける送信完了の論理値（sent）は「false 」である。この場合、サーバ装置１（b1）は、検索されたレコードに含まれる受信者へのパケットＩＤ（target_pid=0x126）を用いてpublish メッセージを再送する。サーバ装置１（b1）からのpublish メッセージの再送を受けたクライアント装置２（s2）は、pubrelメッセージを受信するまでは、再送されたpublish メッセージを受信しても受信処理せずに破棄するから、重複して受信処理を行なうことはない。
【０１９５】
レコードが検索でき、送信先のクライアント装置２（s2）から、サーバ装置１（b1）へpubrecメッセージが送信された後であれば、検索されたレコードにおける送信完了の論理値（sent）は「true」である。サーバ装置１（b1）は、再送されたpublish メッセージに基づくpublish メッセージの再送を行なわない。クライアント装置２（s2）へ重複してメッセージが到達することはない。
【０１９６】
サーバ装置１（b1）は、切断される前にパブリッシャであるクライアント装置２（p1）から受信したpublish メッセージについて、クライアント装置２（s2）へのpublish メッセージの送信を行なう際に、当該クライアント装置２（s2）とのセッションＭが切断されているケースが考えられる。このケースは、ブローカ・サブスクライバ間の切断であるから後述にて説明する。
【０１９７】
切断のタイミングが図４０に示した状態以外である場合、サーバ装置１（b1）は、各セッションにおけるMQTTモデルにおけるネットワークコントローラの送信バッファに残存しているメッセージの有無に基づく処理（図１５から図１７）により、中断されたやり取りが再開され、メッセージのやり取りが完了する。図４１、図４２に示したように、pubrecメッセージがパブリッシャへ到達した後は、各セッションにおけるpubrelメッセージ及びpubcomp メッセージのやり取りが実行される。
【０１９８】
このように、セッション毎におけるQoS =2のみならず、セッションＪ、セッションＬ及びセッションＫ、並びにセッションＪ及びセッションＭを跨ぐメッセージの到達保証を、セッションＪが切断された場合でもQoS =2で達成することができる。
【０１９９】
（４．２．２）ブローカ・サブスクライバ間
図４０に示した状態で、サブスクライバであるクライアント装置２（s1）と、ブローカであるサーバ装置１（b2）との間で確立されていたセッションＫが切断された場合のQoS =2の到達保証について説明する。図４３は、サーバ装置１（b2）におけるサブスクライバとのセッション切断検知時の処理手順の一例を示すフローチャートである。
【０２００】
サーバ装置１（b2）の制御部１０は、自身に通信接続していたサブスクライバであるクライアント装置２との切断を検知すると（ステップＳ６０１）、図１５Ａのフローチャートに示したMQTTの中途メッセージ情報の処理手順にしたがって、切断されたセッションの接続先のクライアント装置２向けのpublish メッセージが送信バッファに残存しているか否かを判断する（ステップＳ６０２）。残存していると判断された場合（Ｓ６０２：ＹＥＳ）、制御部１０は、このpublish メッセージを中途メッセージ情報（パケットイメージと送信先のクライアント装置２の識別情報）としてデータベース３（「keep_mqtt 」テーブル）に記憶する（ステップＳ６０３）。送信バッファに残存していたpublish メッセージは消去される。
【０２０１】
制御部１０は、一時記憶しているパケットＩＤ対応情報（pid_map_b2u 又はpid_map_u2u ）の内、切断されたセッションの接続先のクライアント装置２を受信者とするレコードをデータベース３に自身の識別情報（broker_id）を対応付けて記憶する（ステップＳ６０４）。制御部１０は、記憶したレコードを、一時記憶から削除する（ステップＳ６０５）。
【０２０２】
制御部１０は、切断されたセッションの接続先のクライアント装置２が再度自身へ通信接続のリクエストを送信してきたか否かを判断する（ステップＳ６０６）。送信してきたと判断された場合（Ｓ６０６：ＹＥＳ）、制御部１０は、図４のフローチャートに示した処理手順（Ｓ１−Ｓ３：ＮＯ、Ｓ１６）を実行する。制御部１０は、自身が記憶し、接続先のクライアント装置２を受信者とするパケットＩＤ対応情報のレコードをデータベース３（pid_map_b2u ）から参照する（ステップＳ６０７）。制御部１０は、ステップＳ１６の状態情報の復元の一環として、読み出したレコード（pid_map_b2u 又はpid_map_u2u ）を一時記憶部１３による一時記憶に戻す（ステップＳ６０８）。
【０２０３】
続いて制御部１０は、図１５Ｂのフローチャートに示した処理手順にしたがい、接続先のクライアント装置２へのpublish メッセージの送信は完了しているか否かを判断する（ステップＳ６０９）。送信が完了していないと判断された場合（Ｓ６０９：ＮＯ）、制御部１０は、データベース３から、接続先のクライアント装置２へ送信されるべきであったメッセージ情報（中途メッセージ情報（「keep_mqtt」テーブル））をデータベース３から読み出す（ステップＳ６１０）。制御部１０は、読み出したパケットＩＤをそのまま含むパケットイメージでpublish メッセージを送信する（ステップＳ６１１）。そして制御部１０は、パケットＩＤ対応情報を参照し、再送したpublish メッセージに対応するpubrecメッセージをパブリッシャ側のサーバ装置１（b1）へ送信し（ステップＳ６１２）、切断検知時の処理を終了し、以後のMQTTモデルに基づくメッセージのやり取りを続行する。図４のフローチャートに示したステップＳ１８の処理が終了し、サーバ装置１（b2）は配信処理を続行する（Ｓ９）。
【０２０４】
ステップＳ６０９にて、送信は完了していると判断された場合（ＳＳ６０９：ＹＥＳ）、制御部１０は切断検知時の処理をそのまま終了する。またステップＳ６０６にて、送信されていないと判断された場合（Ｓ６０６：ＮＯ）、制御部１０は、切断検知時の処理をそのまま終了する。この場合制御部１０は、図４のフローチャートのＳ９へ処理を進めて配信処理を続行する。なおステップＳ６０６において送信されないと判断された場合、データベース３に記憶される各クライアント装置２の接続情報（「connections 」）を確認して自身ではないと判断してもよい。
【０２０５】
一方、切断された先のクライアント装置２（s1）が新たに通信接続をリクエストした先のサーバ装置１における処理について説明する。新たな接続先のサーバ装置１は、新たな通信接続のリクエストに対し、図４のフローチャートに示した処理手順を実行する。この場合、セッション情報がデータベース３（「keep_sub」テーブル）に記憶されているので、接続先のサーバ装置１は、ステップＳ１６にて状態情報を復元する。
【０２０６】
サーバ装置１は、データベース３から接続先のクライアント装置２（s1）への送信に係るパケットＩＤ対応情報（pid_map_b2u ）を検索し、検索された場合にはこれを読み出して状態情報の一部として復元する（Ｓ１６）。新たな接続先であるサーバ装置１は、図１５Ｂの処理手順にしたがって、データベース３の保存メッセージ及び配信先情報又は中途メッセージ情報（「store 」及び「store_target_broker_user」テーブル、又は「keep_mqtt」テーブル）を検索し、メッセージがあると判断された場合（Ｓ１０６：ＹＥＳ）、メッセージを読み出してクライアント装置２へ送信する（Ｓ１０７）。制御部１０は、送信したメッセージをデータベース３から削除する（Ｓ１０８）。制御部１０は、パケットＩＤ対応情報から、publish メッセージの送信元（他のサーバ装置１又はパブリッシャ）へ向けて、pubrec メッセージを送信し、pubrelメッセージ及びpubcomp メッセージのやり取りを完了させる。これによりデータベース３からの配信（Ｓ１８）を終了する。
【０２０７】
図４３のフローチャートに示した処理手順を具体的に説明する。図４０におけるセッションＫが、サーバ装置１（b2）がクライアント装置２（s1）へ（30）のタイミングでpublish メッセージを送信する前に切断されるケースが考えられる。このケースでは、keep接続の処理（図９、図１０から図１４）により、切断されている間に配信されたメッセージは、保存メッセージ及び配信先情報（「store 」及び「store_target」テーブル）として記憶される（クライアント装置２（s2）がkeep接続している場合）。再接続後にサーバ装置１（b2）又は新たなサーバ装置１の処理によってデータベース３から配信される（クライアント装置２（s1）がkeep接続している場合）。再接続後のサーバ装置１では、切断されたクライアント装置２を対象とするパケットＩＤ対応情報を復元できるので、既にクライアント装置２がpublish メッセージを受信処理済みであるか否か（pubrecメッセージを送信しているか否か）を把握することができ、メッセージを重複して送信することなくQoS =2を達成できる。
【０２０８】
セッションＫが、サーバ装置１（b2）がクライアント装置２（s1）へ（30）のタイミングでpublish メッセージを送信した後、pubrecメッセージを受信する前に切断されるケースも考えられる。このケースでは、再接続後にサーバ装置１（b2）又は新たなサーバ装置１の処理によって、データベース３の中途メッセージ情報（「keep_mqtt 」テーブル）を参照した処理（図１５から図１９）により、中断されたやり取りが再開され、メッセージのやり取りが完了する。
【０２０９】
また、図４０に示した例で、パブリッシャであるクライアント装置２（p1）から受信したpublish メッセージについて、サーバ装置１（b1）がクライアント装置２（s2）へのpublish メッセージの送信を行なう際に、当該クライアント装置２とのセッションＭが切断されているケースもブローカ・サブスクライバ間の切断である。セッションＭが切断されるケースでは、切断中にクライアント装置２（s2）が受信すべきメッセージは、識別情報「s2」とする配信先情報と共にデータベース３（「store 」及び「store_target」テーブル）に記憶される（クライアント装置２（s2）がkeep接続している場合）。そしてこのときサーバ装置１（b1）は、受信者を送信先であるはずであったクライアント装置２の識別情報「s2」、受信者へのパケットＩＤを「NULL」とし、送信完了の論理値を「true」とするパケットＩＤ対応情報（pid_map_u2u ）のレコードを作成して記憶している。
【０２１０】
このケースでは、セッションＭが再接続された場合、keep接続の処理により（図４）、記憶されている保存メッセージ及び配信先情報に基づくデータベース３（「store 」及び「store_target」テーブル）からのクライアント装置２（s2）への配信処理が行なわれる。再接続先であるサーバ装置１（b1）では、パケットＩＤ対応情報を復元できる。セッションＪが切断された後、パブリッシャからメッセージの再送を受けたとしても、同一の送信者、同一のパケットＩＤ、クライアント装置２（s2）を受信者とするレコードを検索でき、検索されたレコードの送信完了は「true」であるから、セッションＭが再接続されたとしても再送が行なわない。このようにメッセージの重複到達が回避される。
【０２１１】
このケースにおいてクライアント装置２（s2）が別のサーバ装置１に通信接続した場合も、データベース３（「store 」及び「store_target」テーブル）から配信される。この場合も、別のサーバ装置１にて復元されるパケットＩＤ対応情報（pid_map_u2u ）によって、既に送信済みであることが認識されて重複した送信が回避される。
【０２１２】
（４．２．３）ブローカ・ブローカ間
パブリッシャからサブスクライバへのメッセージを仲介する２つのブローカ間で確立されていたセッションが切断された場合の到達保証について説明する。ブローカ間のセッションは上述したようにkeep接続が選択されている。ブローカ間のセッションの切断（図４０におけるセッションＬの切断）については、keep接続に対する保存メッセージの記憶（「store 」）と、（２．２．３）で説明した切断されている他のサーバ装置１を経由して送信されるメッセージであったことを示すブローカ経由の配信先情報（「store_target_broker_user」テーブル）の記憶とをパケットＩＤ対応情報と共に用いて処理を行なう。
【０２１３】
QoS =2の場合、ブローカ間のセッションが切断された場合のサーバ装置１による処理は、QoS =1について図２４のフローチャートに示した処理手順と基本的に同様である。ただしQoS =2の場合には、ステップＳ３０６で送信するpubackメッセージではなくpubrecメッセージであり、ステップＳ３１６で保存メッセージを削除するステップＳ３１５のトリガはpubackメッセージではなく、pubcomp メッセージを受信することである。そしてステップＳ３０５にて記憶される「本来であれば他のサーバ装置１とセッションを確立しているクライアント装置２へ送信されていたはずのメッセージ」とその配信先情報（「store 」及び「store_target_broker_user」テーブル）に、送信完了しているか否か（pubrecメッセージをその時点で受信しているか否か）の情報を共に記憶する。
【０２１４】
ブローカ間が切断された場合の処理について、具体例を挙げて説明する。ブローカ間のセッションが切断された場合の処理について具体例を挙げて説明する。図４４から図４６は、ブローカ間のセッションが切断された場合の処理の例を示す説明図である。図４４の例で示される装置の接続構成は、クライアント装置２（s2）を省略している点以外は図３８にて示した例と同一である。
【０２１５】
図４４は、ブローカであるサーバ装置１（b1, b2）間のセッションが切断された場合にサーバ装置１の一時記憶部１３及びデータベース３に記憶される情報の内容例を示している。図４４に示した例は、QoS =1の場合の図２５を参照して説明した処理と、切断が検知されるまで同様である。図４４のQoS =2の場合には、各サーバ装置１がパケットＩＤ対応情報を記憶している点で異なる。
【０２１６】
図４５は、図４４に示した状態から、ブローカ間のセッションＬが再確立された後の処理を示し、サーバ装置１（b2）と、サブスクライバであるクライアント装置２（s1）との間のセッションＫが維持されている場合の処理を示している。図４４で説明したように保存メッセージ及びブローカ経由の配信先情報がデータベース３（「store 」及び「store_target_broker_user」テーブル）に記憶されている。これにより、QoS =1の場合は、ブローカ間のセッションＬが切断された場合には、サーバ装置１（b2）からクライアント装置２（s1）へのメッセージの送信がなされたかが不明であるため、サーバ装置１（b2）から念のためにメッセージを送信しておき、確実に送信することが達成できた。QoS =2の場合は、これらの情報とパケットＩＤ対応情報との併用により、１回の送信（Excactry once ）とすることができる。
【０２１７】
具体的には、QoS =2の場合、まず図４５に示すようにセッションＫが維持されている場合には、サーバ装置１（b2）からサブスクライバであるクライアント装置２（s1）へパケットＩＤが採番できてパケットＩＤ対応情報（pid_map_b2u ）が記憶されるから、そのままパブリッシャからのpublish メッセージがクライアント装置２（s1）に到達しているはずである（sent=true になる）。仮にセッションＫが切断された場合であっても、keep接続及び中途メッセージ情報（keep_mqtt ）等に基づいてブローカであるサーバ装置１（b2）の制御により、送信しようとされていたpublish メッセージはクライアント装置２（s1）へ送達されるはずである。したがってQoS =2では送信を１回とするために、対応するパケットＩＤ対応情報が記憶されている場合には、保存メッセージ及びブローカ経由の配信先情報からの送信は回避されるべきである。そこでサーバ装置１（b2）は、データベース３（「store 」及び「store_target_broker_user」テーブル）から、自身（b2）宛てに、パケットＩＤ「0x125 」で、クライアント装置２（s1）向けに送信されたメッセージがあることを認識した場合に、ここからの送信をしないように処理を行なう。具体的にはサーバ装置１（b2）は自身宛のサーバ装置１（b1）からのメッセージのパケットＩＤ「0x125 」で識別情報「s1」を受信者としたパケットＩＤ対応情報のレコードがあるか否かを確認する。ブローカ間のセッションＬが切断された場合には、再確立後MQTT上のやり取りが再開されず、pubrelメッセージを受信しないため、対応するパケットＩＤ対応情報のレコードが削除されずに残っているはずである。したがってサーバ装置１（b2）は、サーバ装置１（b1）から受信したメッセージのパケットＩＤと、そのメッセージをサブスクライバへ送信する際に用いるパケットＩＤとの対応関係を示すパケットＩＤ対応情報（pid_map_b2u ）から、ブローカ経由の配信先情報に対応するレコード（source_broker_id==broker_id(b1), target_user_id=user_id(s1), source_pid==broker_pid(0x125)）を検索により抽出できる。この場合、サーバ装置１（b2）は、データベース３に記憶してあるブローカ経由の配信先情報（「store_target_broker_user」）からの送信は行なわない。QoS =1の場合は、メッセージがデータベース３に記憶されていれば再送されていたのに対し、QoS =2では上述のように既に送信がされているはずである。このように同一メッセージに基づくpublish メッセージの重複を回避できる。なおサーバ装置１（b2）は、pubrelメッセージを受信できないために残っているブローカ経由の配信先情報と対応するパケットＩＤ対応情報（pid_map_b2u）を、その配信先情報と共にここで削除する。ブローカ経由の配信先情報に対応するレコードを検索で抽出できない場合は、サーバ装置１（b2）はブローカ経由の配信先情報からの送信が行ない、この場合、送信先のクライアント装置２からのpubrecメッセージ、pubcomp メッセージの受信により、配信先情報（「store_target_broker_user」）を削除する。
【０２１８】
図４６は、図４４に示した状態から、ブローカ間のセッションＬが再確立された後の処理を示す。図４６は更に、ブローカ間が切断されている間に、サブスクライバであるクライアント装置２（s1）が、サーバ装置１（b1）との間のセッションを切断し、サーバ装置１（b1）へ接続した場合の例を示している。
【０２１９】
図４６に示したケースでは、サーバ装置１は特定の処理を実行する。図４７は、QoS =2におけるブローカ間のセッションの再確立後のメッセージ送信処理の一例を示すフローチャートである。図４７の処理は例えば、図２４のフローチャートに示した処理手順の内、ステップＳ３０９とステップＳ３１０の間に判断処理を加え、その判断処理でＹＥＳと判断されたときのみ行なう。判断処理とは、切断されていたセッションの相手のブローカに接続していたサブスクライバであるクライアント装置２が相手のブローカと通信接続を切断したか否かである。
【０２２０】
サーバ装置１の制御部は、データベース３（「store 」及び「store_target_broker_user」テーブル）に記憶されているブローカ経由の配信先情報を参照する（ステップＳ８０１）。ブローカ経由の配信先情報は、パブリッシャ側のブローカ（送信者）であるサーバ装置１（図４０においてはサーバ装置１（b1））が記憶する情報である。制御部１０は、ブローカ経由の配信先情報における送信完了しているか否かの情報（他のサーバ装置１からpubrecメッセージを受信しているか、[already_sent]）、及び再送しているか否かの情報（再送時のパケットＩＤがNULLでないか）を参照する（ステップＳ８０２）。制御部１０は、再送されているか否か（再送時のパケットＩＤがNULLでないか否か）を判断し（ステップＳ８０３）、再送されていると判断された場合（Ｓ８０３：ＹＥＳ）、送信が完了しているか否かの論理値を参照し、完了しているか否かを判断する（ステップＳ８０４）。送信が完了していると判断された場合（Ｓ８０４：ＹＥＳ）、制御部１０は、配信先情報における再送時のパケットＩＤを用いてpubrelメッセージを送信し（ステップＳ８０５）、以後のMQTTモデルに基づくメッセージ処理を続行し、処理を終了する。
【０２２１】
ステップＳ８０４にて送信が未完であると判断された場合（Ｓ８０４：ＮＯ）、制御部１０は、配信先情報における再送時のパケットＩＤを用いてpublish メッセージを再送し（ステップＳ８０６）、以後のMQTTモデルに基づくメッセージ処理を続行し、処理を終了する。
【０２２２】
ステップＳ８０３にて再送されていないと判断された場合（Ｓ８０３：ＮＯ）、制御部１０は、ステップＳ８０１で参照した配信先情報と、送信者（[source_user(broker)_id] ）及び受信者（[target_user(broker)_id]）が同一であるパケットＩＤ対応情報のレコードをデータベース３から検索により抽出できるか否かを判断する（ステップＳ８０７）。
【０２２３】
ステップＳ８０７にて検索により抽出できないと判断された場合は（Ｓ８０７：ＮＯ）、読み出された配信先情報に記憶されているパケットＩＤ対応情報の有無に応じた処理（情報が無い場合であっても実行するか否か）の可否を示す情報が、可を示すか否かを判断する（ステップＳ８０８）。
【０２２４】
不可を示すと判断された場合（Ｓ８０８：ＮＯ）、制御部１０は、処理をそのまま終了する。可を示すと判断された場合（Ｓ８０８：ＹＥＳ）、この場合、サブスクライバ側のブローカからパブリッシャ側のブローカへのpubrecメッセージの送信が未完了である（publish メッセージが送信されていない可能性がある）。制御部１０は、新たなパケットＩＤを採番し（ステップＳ８０９）、採番したパケットＩＤを用いてpublish メッセージをサーバ装置１へ送信し（ステップＳ８１０）、処理を終了する。
【０２２５】
ステップＳ８０７にて検索により抽出できると判断された場合は（Ｓ８０７：ＹＥＳ）、図４５で説明したようにパケットＩＤ対応情報が存在しているので、他のブローカにおける制御により、サブスクライバへ配信がされるはずであるからそのサーバ装置１に処理を任せる。したがって制御部１０は、処理をそのまま終了する。
【０２２６】
図４６を参照して具体的に説明する。サーバ装置１（b1）側ではブローカ間のメッセージについて、図２４のフローチャートに示した処理手順の内で、puslish メッセージが残存していると判断される。（20）のタイミングにおけるpublish メッセージに対するpubrecメッセージを受信していないからである。ただしこのケースでは、残存しているpublish メッセージに基づくサブスクライバへのメッセージの送信は、再確立させたサーバ装置１（b2）を経由して行なうか否かは不明である。サーバ装置１（b2）がクライアント装置２（s1）と切断されているので、サーバ装置１（b1）は、ブローカ間のメッセージについて図４７の処理を実行する。図４６の例では、パケットＩＤ対応情報が記憶されているので（Ｓ８０７）、は特に何も送信されず、処理が終了する。
【０２２７】
なお図４６に示した例においてサーバ装置１（b1）は、クライアント装置２（s1）がサーバ装置１（b1）へセッション確立をリクエストし、これを承諾するとデータベース３における接続先情報を識別情報「b1」に書き換える。この後同期処理が実行され、サーバ装置１（b1及びb2）間で接続情報が共有される。サーバ装置１（b1）は、状態情報を記憶しているクライアント装置２の識別情報「s1」と、データベース３に記憶されている各クライアント装置２の接続先情報（「connections 」）における識別情報「s1」とを照合し（図２４のＳ３０９）、接続先情報でも自身が接続先であると判断する（Ｓ３１０：ＹＥＳ）。そしてサーバ装置１（b1）は、ステップＳ３１１−Ｓ３１３の処理において、後述するようにサーバ装置１（b2）がデータベース３に記憶（移動）したパケットＩＤ対応情報にて、自身を送信者とし、接続してきたクライアント装置２（s1）を受信者とするレコードを検索し、検索されるとそのレコードに記憶されている送信完了の論理値（[sent]）を参照する。論理値が送信完了である場合、そのレコードの受信者向けのパケットＩＤ（[target_pid]）を用いてpubrelメッセージを送信し、送信完了でない場合、同パケットＩＤを用いてpublish メッセージを再送することができる。
【０２２８】
図４６で示す例においてサーバ装置１（b2）側では、サーバ装置１（b1）とのセッションを再確立すると（図２４、Ｓ３０７）、同期処理を行なう（Ｓ３０８）。サーバ装置１（b2）は、状態情報とデータベース３に記憶されている各クライアント装置２の接続先情報（「connections 」）における識別情報「s1」を照合し（Ｓ３０９）、自身が接続先でないと判断する（Ｓ３１０：ＮＯ）。サーバ装置１（b2）は、クライアント装置２（s1）についての状態情報を削除する（Ｓ３１１）。そしてサーバ装置１（b2）は、図４３のフローチャートに示した手順にしたがい、クライアント装置２（s1）との関係におけるパケットＩＤ対応情報（図中のpid_map_b2u ）をデータベース３に記憶（移動）する（Ｓ６０４）。その後、再度通信接続してきていないと判断されるため（Ｓ６０６：ＮＯ）、以後のクライアント装置２（s1）向けの処理はサーバ装置１（b1）側に任される。
【０２２９】
このように、MQTTモデルにおける到達保証のメッセージのやり取りの途中でブローカ間のセッションが切断された場合であっても、パブリッシャであるクライアント装置２からQoS =2が指定されたメッセージの到達保証をクライアント装置２からブローカまでのセッションのみならず、サブスクライバであるクライアント装置２までの経路においてQoS =2とすることができる。
【０２３０】
（５）QoS =2、ブローカダウン保証
ブローカがダウンした場合もメッセージの到達を保証するという前提において、（４）同様に、経路である全てのセッションにてQoS が「２」となるQoS =2が指定されたpublish メッセージのサブスクライバまでの到達について説明する。なお以下の説明でも（４）同様に、当該メッセージのトピックについてサブスクライバであるクライアント装置２がQoS として「２」以外を指定している場合については、説明を省略する。
【０２３１】
図４８は、QoS =2でブローカダウンを保証する際の処理を示す図である。図４８で示す装置の構成は、ブローカダウンを保証しない場合について説明した図３８で示した例と同一である。図４８と図３８とを比較すると明らかであるように、差異はパケットＩＤ対応情報の記憶先である。QoS =2で更にブローカダウンを保証する場合、keep接続におけるデータベース３（store, store_target ）の記憶に加え、各サーバ装置１がパケットＩＤ対応情報を一時記憶部１３に一時記憶するのではなく、いずれのブローカの情報であるかを対応付けてデータベース３に記憶し、復旧後にパケットＩＤの異なるセッション間の一時記憶を復旧することを可能にする。
【０２３２】
（５．１）正常運用時
ブローカがダウンした場合にメッセージの到達を保証する場合、ダウンしたことを自身で検知できないので、ダウンした場合の処理に切り替えるといったことができない。この場合サーバ装置１は、一時記憶して用いる情報（送信バッファ、及びパケットＩＤ対応情報）、データベース３に記憶して用いる。QoS =2の場合、ブローカダウンを保証する場合もサーバ装置１は基本的に、図３９のフローチャートに示した処理手順を実行する。ただし、パケットＩＤ対応情報の記憶先がデータベース３であることと、QoS =1の場合について説明した図２９のフローチャートで示したように、publish メッセージを送信する前に、keep接続しているクライアント装置２が自身に接続している場合は必ず、データベース３（「store 」及び「store_target」又は「store_target_broker 」）にメッセージを記憶する処理を実行する。即ちサーバ装置１は、図２９のフローチャートに示した処理手順の内、Ｓ２２１、Ｓ２２２、Ｓ２２３−Ｓ２２５、Ｓ２２６、Ｓ２２７、Ｓ２２８−Ｓ２２９の処理を、図３９のフローチャートにおけるpublish メッセージの送信処理（Ｓ５０８、Ｓ５１８）の前に行なう。なお図２９におけるpubackメッセージに関する処理に関してはpubrecメッセージの処理に置換される。
【０２３３】
図４８に示すQoS =2の場合でのパケットＩＤ対応情報は、記憶先がデータベース３であって、また具体的内容（記憶処理を行なったサーバ装置１の識別情報（broker_id ）が最初に対応付けられて記憶）が異なる以外は、ダウンを保証外とする場合の処理手順と同様である（図３８を参照した（４．１）における説明）。
【０２３４】
（５．２）切断時
ブローカがダウンした場合もQoS =2が指定されたメッセージの到達を保証する場合において、切断又はダウンが発生したケースについて具体例を挙げて説明する。基本的に、図４８で示したように、パケットＩＤ対応情報の記憶先が常にデータベース３であることを除いては、ダウンを保証しない場合の処理と同様である。ブローカダウン時もメッセージの到達をQoS =2で保証する場合には、publish メッセージの送信の都度、データベース３に事前に保存メッセージとして記憶され、完了する都度に削除されると共に、その際のパケットＩＤ対応情報もデータベース３に記憶されるから、ダウンした場合も復旧時にデータベース３から、それらの情報を参照して状態情報を復旧することができる。この場合具体的にはサーバ装置１は復旧時に、（３）のQoS =1におけるダウン保証の説明で示した図３４のフローチャートの処理手順を実行する。このとき、ステップＳ４０９の対応メッセージは、pubcomp メッセージの受信に読み替えられる。つまり記憶された配信先情報及び保存メッセージは、サーバ装置１におけるpubcomp メッセージの受信をトリガに削除される。
【０２３５】
ブローカダウン時もメッセージの到達をQoS =2で保証する場合、メッセージの送受信に係る多くの情報をデータベース３に記憶することになる。データベース３への更新及び削除の処理は、時間を要するものである。したがってこのケースでは特に、データベース３をＫＶＳで構成し、全てのイベントを書き込みとすることで処理速度を向上させることが期待できる。
【０２３６】
このように、本実施の形態１における通信システム１００では、ブローカダウンを考慮した上でパブリッシャからサブスクライバまでのメッセージの到達保証を実現する。完全なる到達保証を実現するには、各ブローカであるサーバ装置１が全てをデータベース３に記憶することで実現することは可能であるが、処理速度が低下し、Pub/Sub 型メッセージ送受信システムの負荷の軽さの利点を享受できない。本実施の形態における通信システム１００では、システムを利用するユーザのクライアント装置２が、ブローカへ通信接続する際（keep）、そしてブローカ起動時、即ちサブスクライバから接続するブローカを選択する際（ブローカダウン時保証の有無）、ブローカへサブスクライブを実行する際（サブスクライブ時のQoS の指定）、更にメッセージを送信する際に（パブリッシュ時のQoS の指定）、各々で保証レベルを選択することが可能である。
【０２３７】
本開示の実施形態はすべての点で例示であって、制限的なものではないと考えられるべきである。本発明の範囲は、上記した意味ではなく、特許請求の範囲によって示され、特許請求の範囲と均等の意味及び範囲内でのすべての変更が含まれることが意図される。
【符号の説明】
【０２３８】
１  サーバ装置（ブローカ）
１０  制御部
１１  第１記憶部
１Ｐ  サーバプログラム
１２  第２記憶部（データベース）
１３  一時記憶部
１４  通信部
２  クライアント装置（パブリッシャ／サブスクライバ）
２０  制御部
２１  記憶部
２２  通信部
３  データベース
Ｎ  ネットワーク
【図１】
2019176275.tif 000003
【図２】
2019176275.tif 000004
【図３】
2019176275.tif 000005
【図４】
2019176275.tif 000006
【図５】
2019176275.tif 000007
【図６】
2019176275.tif 000008
【図７】
2019176275.tif 000009
【図８】
2019176275.tif 000010
【図９】
2019176275.tif 000011
【図１０】
2019176275.tif 000012
【図１１】
2019176275.tif 000013
【図１２】
2019176275.tif 000014
【図１３】
2019176275.tif 000015
【図１４】
2019176275.tif 000016
【図１５】
2019176275.tif 000017
【図１６】
2019176275.tif 000018
【図１７】
2019176275.tif 000019
【図１８】
2019176275.tif 000020
【図１９】
2019176275.tif 000021
【図２０】
2019176275.tif 000022
【図２１】
2019176275.tif 000023
【図２２】
2019176275.tif 000024
【図２３】
2019176275.tif 000025
【図２４】
2019176275.tif 000026
【図２５】
2019176275.tif 000027
【図２６】
2019176275.tif 000028
【図２７】
2019176275.tif 000029
【図２８】
2019176275.tif 000030
【図２９】
2019176275.tif 000031
【図３０】
2019176275.tif 000032
【図３１】
2019176275.tif 000033
【図３２】
2019176275.tif 000034
【図３３】
2019176275.tif 000035
【図３４】
2019176275.tif 000036
【図３５】
2019176275.tif 000037
【図３６】
2019176275.tif 000038
【図３７】
2019176275.tif 000039
【図３８】
2019176275.tif 000040
【図３９】
2019176275.tif 000041
【図４０】
2019176275.tif 000042
【図４１】
2019176275.tif 000043
【図４２】
2019176275.tif 000044
【図４３】
2019176275.tif 000045
【図４４】
2019176275.tif 000046
【図４５】
2019176275.tif 000047
【図４６】
2019176275.tif 000048
【図４７】
2019176275.tif 000049
【図４８】
2019176275.tif 000050