TCP 受信アダプタの使用法
ここでは、プライマリ TCP 受信アダプタ (EnsLib.TCP.CountedInboundAdapterOpens in a new tab、EnsLib.TCP.CountedXMLInboundAdapterOpens in a new tab、および EnsLib.TCP.TextLineInboundAdapterOpens in a new tab) の使用方法について説明します。
TCP 受信アダプタの概要
InterSystems IRIS® データ・プラットフォームには、すべてが EnsLib.TCP.InboundAdapterOpens in a new tab のサブクラスである以下の受信 TCP アダプタが用意されています。
-
EnsLib.TCP.CountedInboundAdapterOpens in a new tab は、TCP クライアントと TCP リスナがデータのブロックを交換する受信 TCP 接続をサポートします。このブロック長は、ブロックの最初の 4 バイトで指定されます。アダプタは、クライアント・アプリケーションからのデータの意味のある部分を特定するためにブロック長を使用します。
-
EnsLib.TCP.CountedXMLInboundAdapterOpens in a new tab は、XTE サーバの TCP リスナとして機能します。アダプタは XML データをカウントされた TCP 形式で受信し、XML データを InterSystems IRIS にインポートします。その結果は、インスタンス化された InterSystems IRIS オブジェクトとなります。
-
EnsLib.TCP.TextLineInboundAdapterOpens in a new tab は、TCP クライアントと TCP リスナがデータを行終端文字で終了するテキスト文字列として交換する受信 TCP 接続をサポートします。終端文字のデフォルトは新規行文字 (ASCII 10) です。
組み込みのビジネス・サービス・クラス EnsLib.TCP.StatusServiceOpens in a new tab は、EnsLib.TCP.TextLineInboundAdapterOpens in a new tab を使用するビジネス・サービスの重要な例です。このクラスにはコマンド行インタフェースが用意されており、これをコンソール・ユーザやコマンド行スクリプトで使用して、実行中のプロダクションから基本ステータス情報を取得できます。詳細は、"TCP ステータス・サービスの追加" を参照してください。
全般的な動作
それぞれの TCP 受信アダプタが、指定されたポートでデータをチェックして、入力を読み取り、それをストリームとして関連するビジネス・サービスに送信します。ユーザが作成および構成するビジネス・サービスは、このストリームを使用してプロダクションの他の部分と通信します。以下の図は、全体的なフローを示しています。
詳細は、以下のとおりです。
-
アダプタは、構成されたデータ・ソースからの入力を検出するたびに、ビジネス・サービス・クラスの内部 ProcessInput() メソッドを呼び出して、ストリームを入力引数として渡します。
-
ビジネス・サービス・クラスの内部 ProcessInput() メソッドが実行されます。このメソッドは、すべてのビジネス・サービスが必要とする内部情報の保持など、基本的なプロダクション・タスクを実行します。ビジネス・サービス・クラスが継承するこのメソッドは、カスタマイズや上書きを行いません。
-
次に、ProcessInput() メソッドがカスタム OnProcessInput() メソッドを呼び出して、入力オブジェクトを渡します。このメソッドの要件は、このページの後半を参照してください。
応答メッセージは、同じパスを逆向きにたどります。
TCP 受信アダプタを使用するビジネス・サービスの作成
プロダクション内で TCP アダプタを使用するには、ここで説明されているように、新しいビジネス・サービス・クラスを作成します。後で、それをプロダクションに追加して、構成します。
存在しなければ、適切なメッセージ・クラスを作成する必要もあります。"メッセージの定義" を参照してください。
ビジネス・サービス・クラスの基本要件を以下に列挙します。
-
ビジネス・サービス・クラスは Ens.BusinessServiceOpens in a new tab を拡張するものでなければなりません。
-
クラス内の ADAPTER パラメータは EnsLib.TCP.CountedInboundAdapterOpens in a new tab、EnsLib.TCP.CountedXMLInboundAdapterOpens in a new tab、または EnsLib.TCP.TextLineInboundAdapterOpens in a new tab と一致する必要があります。
-
クラスは OnProcessInput() メソッドを実装する必要があります。これについては、"OnProcessInput() メソッドの実装" で説明します。
-
クラスは OnConnect() コールバック・メソッドを実装できます。このメソッドは、TCP 受信アダプタがリモート・システムとの新しい接続を確立するたびに、OnTask() メソッドの後に呼び出されます。
このメソッドを実装する場合は、以下のシグニチャを付与する必要があります。
Method OnConnect(pTimeout As %Numeric) As %Status
新しい接続が確立されるたびに何らかの処理 (ログオン・シーケンスやハンドシェーク・トークンの送信など) を実行する場合は、OnConnect() を実装します。timeout 引数は、TCP 受信アダプタによって自動的に指定されます。この値には、Read Timeout アダプタ設定の値が入力されます。Read Timeout の詳細は、設定のリファレンスを参照してください。
OnConnect() がエラー・ステータスを返した場合は、新しい接続が失敗して、アダプタが切り離されます。トラップされない例外が OnConnect() 内で発生した場合、アダプタはその例外をキャッチして、OnConnect() が実装されていなかった場合と同じように処理を継続します。
その他のオプションと一般情報は、"ビジネス・サービス・クラスの定義" を参照してください。
-
クラスでは、OnInit() メソッドを実装して特殊な設定アクションを実行できます。このメソッドは、%OnNew() メソッドから呼び出します。[接続毎のジョブ] 設定を true に設定すると、リスナが接続を受け入れるために新しいジョブを生成するたびに、OnInit() が %OnNew() から呼び出されます。
-
クラスでは、OnTearDown() メソッドを実装して特殊なティアダウン・アクション (終了処理) を実行できます。このメソッドは、%OnClose() メソッドから呼び出します。具体的には、%OnClose() によって、アダプタの OnTearDown() メソッドが呼び出された後、ビジネス・サービスの OnTearDown() メソッドが呼び出されます。[接続毎のジョブ] 設定を true に設定すると、OnTearDown() は、接続ジョブが閉じられる直前に呼び出されます。
Important:新規のビジネス・サービス・クラスで、OnTearDown() メソッドにカスタム・コードを含める場合、そのビジネス・サービスが適切に機能するように、そのカスタム・コードでスーパークラスの OnTearDown() メソッドを呼び出す必要があります。以下に例を示します。
//Sets a node of the ^%zexample global to the ID of the current process // and invokes the OnTearDown() method of the superclass Method OnTearDown() As %Status { set ^%zexample($i(^%zexample),"onteardown")=$j Return ##super() }
エラーを処理するために、適宜、Try/Catch ロジックを実装する必要もあります。スーパークラス・メソッドを呼び出す方法の詳細は、"##super 構文" を参照してください。
OnProcessInput() メソッドの実装
この節では、アダプタによって異なる OnProcessInput() のメソッド・シグニチャとそのメソッドの実装方法について説明します。
EnsLib.TCP.CountedInboundAdapter の OnProcessInput() のシグニチャ
ビジネス・サービス・クラスで EnsLib.TCP.CountedInboundAdapterOpens in a new tab が使用されている場合は、OnProcessInput() メソッドに次のシグニチャを付与する必要があります。
Method OnProcessInput(pInput As %Library.GlobalCharacterStream,
Output pOutput As %Library.AbstractStream) As %Status
説明 :
-
pInput には TCP クライアントがアダプタに転送した受信データ・ストリームが含まれています。
-
pOutput にはビジネス・サービスが TCP クライアントに提供する可能性のあるすべての応答が含まれています。
EnsLib.TCP.CountedXMLInboundAdapter の OnProcessInput() のシグニチャ
ビジネス・サービス・クラスで EnsLib.TCP.CountedXMLInboundAdapterOpens in a new tab が使用されている場合は、OnProcessInput() メソッドに次のシグニチャを付与する必要があります。
Method OnProcessInput(pInput As %RegisteredObject,
Output pOutput As %RegisteredObject) As %Status
説明 :
-
pInput は Accept Class Names アダプタ設定によって指定された任意のオブジェクトにすることができます。
Accept Class Names の詳細は、設定のリファレンスを参照してください。
-
pOutput には XTE サーバに返される可能性のあるすべての応答が含まれています。
EnsLib.TCP.TextLineInboundAdapter の OnProcessInput() のシグニチャ
ビジネス・サービス・クラスで EnsLib.TCP.TextLineInboundAdapterOpens in a new tab が使用されている場合は、OnProcessInput() メソッドに次のシグニチャを付与する必要があります。
Method OnProcessInput(pInput As Ens.StringContainer,
Output pOutput As Ens.StringContainer) As %Status
説明 :
-
pInput には受信テキスト行が含まれています。
-
pOutput には送信応答文字列 (存在する場合) が含まれています。
OnProcessInput() の実装
すべてのケースにおいて、OnProcessInput() メソッドは以下の一部または全部を実行する必要があります。
-
入力オブジェクト (pInput) を検査して、その使用方法を決定します。
-
ビジネス・サービスから送信されることになる要求メッセージのインスタンスを作成します。
メッセージ・クラスの作成方法は、"メッセージの定義" を参照してください。
-
要求メッセージの場合は、必要に応じて、入力内の値を使用してそのプロパティを設定します。
-
ビジネス・サービスの適切なメソッドを呼び出して、要求をプロダクション内の宛先に送信します。具体的には、SendRequestSync()、SendRequestAsync()、または (あまり一般的ではない) SendDeferredResponse() を呼び出します。詳細は、"要求メッセージの送信" を参照してください。
これらの各メソッドは、ステータス (具体的には、%StatusOpens in a new tab のインスタンス) を返します。
-
必ず出力引数 (pOutput) を設定します。通常、受信した応答メッセージと同じように設定します。この手順は必須です。
-
データ・ソースがその入力に対する確認または応答を期待している場合は、OnProcessInput() がこの応答を作成して、アダプタ経由でデータ・ソースに返送する必要があります。
-
適切なステータスを返します。この手順は必須です。
EnsLib.TCP.TextLineInboundAdapter の例
EnsLib.TCP.TextLineInboundAdapterOpens in a new tab を使用するビジネス・サービス・クラスの例を以下に示します。
Class TestTCPTextLine.AuthorizationTCPService Extends Ens.BusinessService
{
/// Name of the adapter class
Parameter ADAPTER = "EnsLib.TCP.TextLineInboundAdapter";
Method OnProcessInput(pInput As Ens.StringContainer,
pOutput As Ens.StringContainer) As %Status
{
set $ZT = "EXCEPTION"
set st = $$$OK
do {
if ('$isobject($get(pInput))) { quit }
// Input must have the following format: 'PatientCode:ProcedureCode'
set tSubject = pInput.StringValue
$$$TRACE("received line "_tSubject)
set req = ##class(TestTCPTextLine.AuthorizationRequest).%New()
set req.PatientCode = $piece(tSubject,":",1)
set req.ProcedureCode = $piece(tSubject,":",2)
set st = ..SendRequestSync("AuthorizationProcess", req, .resp)
quit:$$$ISERR(st)
set pOutput=
##class(Ens.StringContainer).%New(resp.AuthorizationFlag_
":"_resp.AuthorizationCode)
} while (0)
EXIT
//do ..Adapter.Disconnect()
quit st
EXCEPTION
set $ZT = ""
set st = $$$EnsSystemError
goto EXIT
}
}
ビジネス・サービスの追加と構成
ビジネス・サービスをプロダクションに追加するには、管理ポータルを使用して以下の操作を行います。
-
ビジネス・サービス・クラスのインスタンスをプロダクションに追加します。
-
ビジネス・サービスを構成します。設定の詳細は、設定のリファレンスを参照してください。
ビジネス・サービスを構成するときに、他の設定と一緒に [許可IPアドレス] 設定の値を指定します。[許可IPアドレス] はアダプタで接続を開始する方法を示していることに注意してください。
-
ビジネス・サービスを有効化します。
-
プロダクションを実行します。