Tivoli Service Desk 6.0 Developer's Toolkit Interface Designer の手引き
通信用共通プログラミング・インターフェース (CPIC) は、アプリケーション間通信に必要となるアプリケーション用の一貫した API を提供します。CPIC インターフェースは SNA の LU 6.2 を使用して、1 セットのアプリケーション相互間サービスを作成し、これには次が含まれます。
これらのサービスを TSD Script プログラマーに対して拡張するために、CPIC コマンドが TSD Script 言語内にビルドされています。各プラットフォーム間で一貫性を確保するために、基本 APPCマクロを介して CPIC が選択されています。
本書のこの項では、TP をビルドするための CPIC の使用法を TSD Script プログラマーに説明します。 SAA CPIC プログラミングの詳細については、IBM 資料の CPI コミュニケーション・インターフェース解説書 (SC88-7217) を参照してください。
CPIC は、作業するすべての CPIC コマンドにインストールする必要があります。CPIC が適切にインストールされていない場合には、 CPIC コマンドを使用すると、Tivoli Service Desk (TSD) Developer's Toolkit によってエラー・メッセージが表示されて、その CPIC をロードできなかったことが示されます。
APPC は拡張対等通信です。
基本会話とは、アプリケーションが標準バイト・ストリーム形式でデータを交換する会話タイプです。この形式では (LL と呼ばれる) 2 バイト長のフィールドが含まれていて、後に続くバッファーの長さを指定します。LL データの各グループは 論理レコードと呼ばれます。
会話とは、データを交換するために CPIC または APPC を使用する 2 つのアプリケーション間の論理結合のことです。この会話には、 マップ式 と 基本の 2 つのタイプがあります。会話では、セッションを使用してアプリケーション間が接続されます。CPIC アプリケーションは、他の CPIC アプリケーションと会話するのと同じ方法で APPC アプリケーションと会話することができます。
DDF (データ記述ファイル) とは、TSD Script レコード構造と送信されたバイト・バッファー間の関係をマップするために使用されるファイルです。
LU (論理装置) は実際的には 1 つの仮想計算機です。それぞれの物理マシンを LU として指定できると同時に、複数の LU を 1 つの物理マシン上に構成することもできます。CPIC は LU タイプ 6.2 のノードだけを使用することに注意してください。
マップ式会話とは、パートナー間で事前定義形式の任意のデータ・レコードを交換できる会話タイプのことです。
モード名は、会話中に LU 間のセッションのプロパティーを指定するために APPC で使用されます。これらのプロパティーには、サービス・クラスが含まれています。
ノード・サービスは、LU の基本ユーティリティー機能を提供する 1 つまたはセットのアプリケーションです。提供されるサービスには、サイド情報の操作、アプリケーション開始処理、およびアプリケーション終了処理が含まれます。OS/2 のノード・サービスは Communications Manager (CM) または Communications Manager/2 (CM/2) によって提供されます。
パートナーは、CPIC 会話を介してデータを交換する 2 つの CPIC アプリケーションです。
CPIC 会話は 全二重にすることができます。これは、CPIC 会話中のある特定の時点で、片方のパートナーが送信の許可を得て、もう一方のパートナーが受信状態になる (これがデータ受信可能になる) ことを意味します。受信状態のアプリケーションは、データの送信が必要な時に送信要求を出すことができます。 パートナーにはこの要求が通知されて、要求元のアプリケーションは StatusReceived パラメーターに通知を受信します。
SDN (記号宛先名) は Communications Manager/2 の CPIC 構成名であり、これによってアプリケーションは会話割り振り要求で使用するセットの属性を指示することができます。
セッションとは、2 つの LU 間の論理結合です。LU はこのセッションを介して通信します。
会話を確立しようとする時に CPIC で使用される初期化情報です。 サイド情報にはパートナー LU 名、モード名、および TP 名が含まれています。この情報は会話の前に構成されます。
注: サイド情報は SDN によって参照されます。
SNA ネットワークは LU の論理ネットワークです。
同期レベルは、CPIC 会話が使用する同期のレベルを示します。同期レベルは次の 1 つにすることができます。
SYNC_POINT は、ユーザー・アプリケーションが完全な SAA リソース回復操作、すなわち、 「Take Commit」および「Take Backout」通知をサポートしていることを示します。
注: SYNC_POINT は OS/2 ではサポートされていません。
TP (トランザクション・プログラム) は、会話に参加するために CPIC または APPC コマンドを使用するアプリケーションです。
TP 名はトランザクション・アプリケーションの名前です。この名前はサイド情報に指定されます。オペレーティング・システムによっては、TP 名はターゲット LU のノード・サービス・アプリケーションのテーブル項目を指定することがあります。このテーブルは、TP の開始に必要な情報の検索で使用されます。
アプリケーションが他のプログラムとの会話を開始する時に使用する簡単な例は次の通りです。
TSD Script では、メモリー構造の割り振りサイズを直接制御することはできません。
これは、第 4 世代言語の有用な属性とみなされますが、CPIC アプリケーションの作業では困難な局面を提示することもあります。 CPIC アプリケーションは特定のサイズおよび形式のバイト・バッファーを送信し受信します。パートナー・アプリケーションはローカル・アプリケーションとは異なった形式の記憶域を使用することができ、これには非 Intel 整数および EBCDIC 文字ストリングも含まれます。
データ記述ファイル (または DDF) は異なったバッファー・サイズの可能性をアドレスします。 DDF は送信されるバイト・バッファーのフォームを定義して、フォーマット変換 / 会話を指定します。 TSD Developer's Toolkit はこれらの DDF を、CPIC アプリケーションとの発信と着信の両方のバッファーで "フィルター" として使用します。
DDF の基本構造は次の通りです。
-- ダブル・ダッシュは行の終わりに対するコメントです。 -- 最初のセクションはパートナー・セクションです。 *PARTNER -- 文字変換タイプ EBCDIC=TRUE -- 整数バイト順序 NON_INTEL=TRUE -- 文字変換テーブル。指定しないと、TSD Developer's Toolkit は -- CM/2 AE テーブルを使用します。このデフォルト・テーブルは、 -- ユーザーの使用に不十分な場合があります (たとえば、組み込み -- スペースを x'00') に変換します。より一般的な変換テーブルが -- 必要な場合には、CM/2 変換テーブル・ファイル名を ACSGTAB.DAT -- に設定します。これは CM/2 によって提供されます。その後で、 -- CUSTOM_CONVERT を TRUE に設定します。 CUSTOM_CONVERT=TRUE -- このセクションはフィールド・セクションです。これを使用して、 -- レコードの各フィールドとそのバイト・マッピングおよび変換を -- 記述します。このセクションは本質的に、受信直後 (変換前) -- または送信直後 (変換後) にデータ・バッファーをどのように -- 表示することができるかを示します。 *FIELDS -- Fieldname Type ByteWidth SendUnknowns? Default name CHAR 20 FALSE street CHAR 20 TRUE age INTEGER 20 TRUE birthDate CCYYMMDD 8 FALSE
この例では、パートナー・アプリケーションは非 Intel スタイルの整数 (IBM システム 370 など) の EBCDIC マシン上で実行されます。送信されるレコードは次のように TSD Script に宣言されます。
SomeRecordName IS RECORD name :STRING; street :STRING; age :INTEGER; birthDate :DATE; description:STRING; END;
記述フィールドは DDF に組み込まれません。これは、記述フィールド は CPIC 通信中に転送されないことを表します。
DDF のこのセクションでは、パートナー・アプリケーションのマシン・タイプについて説明します。このセクションの始めには、テキスト *PARTNER のマークがあります。パートナー・セクションは、TSD Developer's Toolkit が実行するデータ変換のタイプを示します。たとえば、EBCDIC=TRUE の設定では、パートナー・アプリケーションとの通信時にすべての文字ストリングを EBCDIC に (あるいは EBCDIC から) 変換することを示します。
パートナー・セクションでは、次の属性を設定しなければなりません。設定されない属性では、指示されてデフォルト値がとられます。
この DDF セクションは、CPIC データ・バッファーでパックまたはアンパックされるフィールドおよびフィールド・タイプを指定します。DDF のこのセクションは "*FIELDS" を含む行で開始します。 フィールド・セクションの各行は 1 つの TSD Script 転送済みレコード・フィールドに適用されます。このような行の形式は次の通りです。
{fieldname} {fieldtype} {bytewidth} {sendunknowns?} {default}
空白文字がそれぞれの列を分割しています。列定義は次の通りです。
$INCLUDE コマンドは DDF の編成を単純化します。 このコマンドは、 他のファイルを動的に "リンク" する機能を提供します。 TSD Developer's Toolkit が $INCLUDE コマンドを検出すると、指定された DDF をロードして、そのフィールド定義を現行の DDF に配置します。
$INCLUDE コマンドは、フィールド・セクションの任意の位置に組み込むことができます。 $INCLUDE コマンドの形式は次の通りです。
$INCLUDE({DDFname})
ファイルが現行ディレクトリー中にない場合には、TSD Developer's Toolkit はファイルで DPATHを検索します。これが見つからない場合には、TSD Developer's Toolkit がエラーを戻します。
$SIZEOF コマンドは組み込みファイルのサイズを再計算しますので、別のフィールドが追加された場合に、組み込みファイルを手動で再カウントする必要はありません。
$SIZEOF および $INCLUDE コマンドは、ベクトル化バッファーの設定なと、特別な場合に使用されます。これらは、次の通り組み合わせで使用することができます。
*PARTNER EBCDIC =TRUE NON_INTEL =TRUE CUSTOM_CONVERT =TRUE *FIELDS GDS1310 INT 2 TRUE 4880 GDS1311LEN INT 2 TRUE $SIZEOF(1311.DDF) + 2 $INCLUDE(1311.DDF) GDS1549LEN INT 2 TRUE $SIZEOF(1549.DDF) + 2 $INCLUDE(1549.DDF) DataLen INT 2 TRUE $SIZEOF(RTRNDATA.DDF) + 2 $INCLUDE(RTRNDATA.DDF)
DDF 処理で認識されるタイプは次の通りです。
OS/2 CPIC アプリケーションの作成を試みる前に、知っておく必要があるいくつかの詳細事項があります。これらの一部は、ユーザー・システム上にあるノード・サービスのタイプによってグループに分けることができます。
ノード・サービスが TP を設定して着信割り振りを受信するという方法のために、OS/2 CPIC アプリケーションを SNA サービス TP にすることはできません。着信割り振りの操作方法を要約した次のステップを検討してください。
TP をセットアップしたい TSD Script アプリケーションが複数ある場合には、特別なセットアップを行なう必要があります。 Communications Manager/2 では、1 つの TP 定義の OS/2 アプリケーション PATH およびファイルとして指定できるのは kml.exe だけです。他のものでは、次のコマンドを含む OS/2 コマンド・ファイルを作成します。
SET APPCTPN={your TP name} START /C KML /U{path to your KB} {your KB name} EXIT
Communications Manager/2 では、複数の会話を受け入れる単一 CPIC プロセスを使用することができます。 さらに、CPIC アプリケーションは、その前に Accept コマンドが出されていないかぎり、1 つの Initialize コマンドを出すことができます。
この項には、簡単な CPIC アプリケーションを作成するプロセスの簡単な事例研究が示されています。アプリケーションを設計して、ファイル転送を完了します。
CPIC の利点を図示するために、この事例研究には 2 つのモジュールがあります。 最初の例のモジュールでは、アプリケーションが作成されます。 2 番目の例のモジュールでは、パフォーマンスを向上させるために、そのアプリケーションにいくつかの小変更を行ないます。
この事例研究では、CPIC、Communications Manager/2、および一般的な通信処理に慣れている、という幾つかの前提事項があります。たとえば、Communications Manager/2 CMSETUP ユーティリティーの使用に慣れているものと仮定されています。
開始するには、REXX で作成されたパートナー・アプリケーションを検討してください。
REXX パートナー・アプリケーションは RCV.CMD の名前が付けられます。本質的に、アプリケーションが現在データを送信していないことを受信状況パラメーターが指示するまで、このアプリケーションはデータを送信 (それを語幹変数に保管) します。
次のコードの例は、このアプリケーションに関する追加記述を提供するための説明です。
/* RCV.CMD */ /* Receives data strings, building a buffer of all data. /*Upon completion of*/ /* receiving, sends back the buffer. */ /* CPIC commands used: CMACCP */ /* CMCFMD */ /* CMDEAL */ /* CMRCV */ /* CMSEND */
/* a few useful constants */ CM_OK = 0 /* status received */ CM_SEND_RECEIVED = 1 CM_CONFIRM_RECEIVED = 2 /* data received */ CM_NO_DATA_RECEIVED = 0
MaxLength = 257; BufferLen = 0; FileBuffer.0 = 0; 'CPICREXX'
address cpicomm 'CMACCP Conv_ID RetC'; if \(RetC = CM_OK) then do SAY 'ACCP = 'Retc end;
'CMRCV Conv_ID Data MaxLength DataReceived ReceivedLength StatusRecvd ReqToSendRecvd Retc'; if \(RetC = CM_OK) then do SAY 'RCV = 'Retc end;
do while (RetC = CM_OK) & (StatusRecvd \= CM_SEND_RECEIVED) if (DataReceived \= CM_NO_DATA_RECEIVED) then do /* SAY Data */ FileBuffer.0 = FileBuffer.0 + 1; i = FileBuffer.0; FileBuffer.i = Data; end; if (StatusRecvd = CM_CONFIRM_RECEIVED) then do 'CMCFMD Conv_ID RetC'; end; 'CMRCV Conv_ID Data MaxLength DataReceived ReceivedLength StatusRecvd ReqToSendRecvd Retc'; if (RetC \= CM_OK) then do SAY 'RCV = 'Retc end; end;
SAY 'Re-transmitting file'
DO i = 1 TO FileBuffer.0 BufferLen = LENGTH(FileBuffer.i); Data = FileBuffer.i; 'CMSEND Conv_ID Data BufferLen ReqToSendRecvd RetC'; if (RetC \= CM_OK) then do SAY 'SND = 'Retc end; END; 'CMDEAL Conv_ID RetC'; address cmd 'EXIT'
このアプリケーションのゴールは、テキスト・ファイルを読み取って、各行をパートナー・アプリケーションに送信することです。アプリケーションがファイル転送を完了した後、同じファイルの受信バックを再開して、表示ウィンドウに各行を表示します。
ステップ 3 から開始して、Communication Manager/2 のサイド情報テーブルに項目を設定します。サイド情報テーブルは会話の初期化の時に使用されます。初期化では、次の通り行われます。
このメソッドを使用して、ハード・コーディングのサイト固有情報なしで CPIC アプリケーションを作成することができます。また、これによって、このタイプの情報にアクセスするための CPIC アプリケーションのすべての標準メソッドも提供されます。
ステップ 8 から開始して、TP 定義を作成します。この項目は、特定の TP の開始方法をノード・サービスに通知します。
会話が割り振られると、その割り振りを要求した LU は、ターゲット LU ノード・サービス・システムに必要な TP 名を送信します。ノード・サービス・システムは、その TP 名がシステムに定義されているかどうかを調べるためにチェックします。それが定義されている場合には、ノード・サービスは TP の開始方法の指示に従います。アプリケーションを正常に開始できる場合には、(TP で開始される Attach Manager が設定される時) それを行ないます。その後、TP は CPICAcceptを出します。 要求元 LU が成功指示を受け取ると、会話が開始されます。
この REXX アプリケーションでは、OS/2 コマンド・プロセッサーが開始されます (CMD.EXE)。パラメーター・ストリングは、コマンドの完了 (/C) 時に終了するための CMD.EXE、およびどのコマンドを実行する (RCV.CMD) かを通知します。
この事例研究の次の部分は、OS/2 コマンド行から RCV.CMD ファイルを開始します。
これによって、2 つのアプリケーション間でソース・ファイルを相互に受け渡しして、その結果をウィンドウに表示します。
ダブル転送では、完了までしばらく時間がかかることがあります。ウィンドウのファイル・リストの下に、時間の結果が示されます。
さらに、ファイルの各行の行番号も示されます。これらの番号はテキスト・ファイルの各行とともに受け渡しされます。
次の番号付き行のこのセクションは、ファイルに関する記述です。
1 2 KNOWLEDGEBASE FILESND; 3 4 ROUTINES 5 PROCEDURE DoConversation(VAL Args:List of String); 6 (* sdn, infile *) 7 8 9 PRIVATE 10 11 CONSTANTS 12 CPIC_SUCCESS IS 1; 13 14 TYPES 15 FileRec IS RECORD 16 LineNbr:Integer; 17 Buff:String; 18 END; 19 20 ROUTINES 21 22 FUNCTION RcvData(REF w:WINDOW, VAL Conv:Conversation) :INTEGER IS 23 VARIABLES 24 totalBuff :FileRec; 25 dataRcvd :integer; 26 statRcvd :integer; 27 reqTSRcvd :integer; 28 rc :integer; 29 ACTIONS 30 IF (not(Known(w))) THEN 31 WinCreateScrollWindow($DESKTOP,w, 32 $NullHandler, 1,1,67,7, 'FileSnd','', 0, $WinBorder+ $WinTitle+ $WinHScroll+ $WinVScroll+ $WinSysMenu+ $WinResize); END; 33 REPEAT 34 rc := CPICReceive(Conv,'FILEREC.DDF', totalBuff,DataRcvd, StatRcvd,ReqTSRcvd); 35 IF (rc > 0) THEN 36 IF ((StatRcvd = $CPICConfirmReceived) or 37 (StatRcvd = $CPICConfirmSend Received)) THEN 38 rc := CPICConfirmed(Conv); 39 END; 40 totalBuff.buff := StrTrim (totalBuff.buff); 41 WinWriteLn(w,totalBuff.lineNbr:5&' :'&totalBuff.buff); 42 END; 43 UNTIL ((rc <> 1) OR ((StatRcvd = $CPICSendReceived) OR 44 (StatRcvd = $CPICConfirmSend Received))); 45 Exit(rc); 46 END; -- RcvData 47 48 49 --------------------------------------------- 50 -- 説明: 指定されたファイルに読み込み、 指定された SDN を介して指定された 51 -- パートナーに、各行を cpic 経由で 送信します。 52 --------------------------------------------- 53 PROCEDURE DoConversation(VAL Args:List of String) IS 54 VARIABLES 55 Conv :Conversation; 56 fRec :FileRec; 57 ReqTSRcvd:INTEGER; 58 rc :INTEGER; 59 inf :FILE; 60 w :WINDOW; 61 t1,t2 :TIME; 62 ACTIONS 63 t1 := $NOW; 64 IF (ListLength(Args) <2) THEN WinMessageBox($DESKTOP,?ops? $MBOK,?ML FILESND {SDN} {INFILE}?; Exit; END; FOpen(inf,Args[2],$Read); rc :="CPICInitialize(Conv,Args[1]);" IF (rc <CPIC_SUCCESS) THEN WinMessageBox($DESKTOP, ?PIC Error?$MBOK, ?nit returns ?rc); Exit; END; rc :="CPICSetSyncLevel(Conv," $CPICNone); IF (rc <CPIC_SUCCESS) THEN WinMessageBox($DESKTOP,?PIC Error?$MBOK, ?SL returns ?rc); END; rc :="CPICAllocate(Conv);" IF (rc < CPIC_SUCCESS) THEN WinMessageBox($DESKTOP, ?PIC Error?$MBOK, ?llc returns ?rc); Exit; END; rc :="CPICSetPrepareToReceiveType" (Conv, $CPICPrepToReceiveFlush); IF (rc < CPIC_SUCCESS) THEN WinMessageBox($DESKTOP, ?PIC Error?$MBOK, ?PTR returns ?rc); END; fRec.lineNbr :="0;" while (FReadLn(inf,fRec.Buff)> <2) THEN 65 WinMessageBox($DESKTOP,'Oops', $MBOK,'KML FILESND {SDN} {INFILE}'); 66 Exit; 67 END; 68 69 FOpen(inf,Args[2],$Read); 70 71 rc := CPICInitialize(Conv,Args[1]); 72 IF (rc < CPIC_SUCCESS) THEN 73 WinMessageBox($DESKTOP, 'CPIC Error',$MBOK, 'Init returns '&rc); 74 Exit; 75 END; 76 rc := CPICSetSyncLevel(Conv, $CPICNone); 77 IF (rc < CPIC_SUCCESS) THEN 78 WinMessageBox($DESKTOP, 'CPIC Error',$MBOK, 'SSL returns '&rc); 79 END; 80 rc := CPICAllocate(Conv); 81 IF (rc < CPIC_SUCCESS) THEN 82 WinMessageBox($DESKTOP, 'CPIC Error',$MBOK, 'Allc returns '&rc); 83 Exit; 84 END; 85 86 rc := CPICSetPrepareToReceiveType (Conv, $CPICPrepToReceiveFlush); 87 IF (rc < CPIC_SUCCESS) THEN 88 WinMessageBox($DESKTOP, 'CPIC Error',$MBOK, 'SPTR returns '&rc); 89 END; 90 91 fRec.lineNbr := 0; 92 while (FReadLn(inf,fRec.Buff) > 0) do 93 fRec.Buff := fRec.Buff & Char(13) & Char(10); -- add CR LF 94 fRec.lineNbr := fRec.lineNbr + 1; 95 rc := CPICSend(Conv, 'FILEREC.DDF', fRec, ReqTSRcvd); 96 IF (rc < CPIC_SUCCESS) THEN 97 WinMessageBox($DESKTOP, 'CPIC Error',$MBOK, 'Send returns '&rc); 98 ExitLoop; 99 END; 100 CPICFlush(Conv); 101 END; 102 FClose(inf); 103 104 IF (rc = CPIC_SUCCESS) THEN 105 CPICPrepareToReceive(Conv); -- Indicates Partner may send now. 106 t2 := $NOW; 107 RcvData(w,Conv); 108 END; 109 110 CPICDeallocate(Conv); 111 WinWriteLn(w,'<<<<<<<<<<<<<<<<<<<<<<<< >>>>>>>>>>>>>>>>>>'); 112 WinWriteLn(w,'Elapsed time for outgoing transmission: '& 113 TimeDif(t2,t1,$SECONDS)&' seconds'); 114 WinWait(w); 115 END; 116 117
先行コード・サンプルを説明する検討は次の通りです。
行 42 には、旧式のコードが入っています。このアプリケーションは当初は $CPICConfirm の同期レベルを使用するために作成され、 RcvData はパートナーによる確認をすべて検出して、それを確認しなければなりません。同期レベルが行 80 で $CPICNone に設定されているので、これが行われません。
行 75 〜 93 には、会話セットアップ・コマンドが入っています。 $CPICNone は会話のデフォルトであるので、設定する必要はありません。
行 90 では、CPICAllocate の後に、タイプを受信する準備が設定されます。これは、 CPICPrepareToReceive の呼び出し時に常に実行されるアクションのタイプを指示します。受信でデータが作動可能になると同時に最後のバッファーが送信されるように、フラッシュが選択されました。
ファイル伝送は行 96-105 で行われます。これが、わずか 2 つの CPIC コマンド (CPICSend と CPICFlush) によって行なわれる、ことに注意してください。行 15-17 に定義された 1 つのレコードが送信されます。
マップ・ファイル FILEREC.DDF は次の通りです。
1 2 *PARTNER 3 EBCDIC = FALSE 4 NON_INTEL = FALSE 5 CUSTOM_CONVERT = TRUE 6 7 *FIELDS 8 LineNbr INTEGER 2 TRUE 9 Buff ASE_STRING VAR TRUE 10
行番号と行目次の両方がパートナー・アプリケーションに送信されます。 REXX アプリケーションはバッファーを 1 つのストリングとして取り扱うので、バッファーを戻すことができ、 TSD Developer's Toolkit はこの 2 つのフィールドをもう一度取り出すことができます。
行 104 では、バッファーをフラッシュします。これによって、CPICSend に渡されるデータが即時にパートナーに送信されます。
ファイルの送信の後、パートナーはデータの送信が開始できると通知されます。 RcvData 関数 (行 22) が着信データを操作します。
RcvData は、エラーがある (会話を割り振り解除するパートナーも含む) か、あるいはアプリケーションが再び送信通知を受け取るまで、着信 FILEREC データを受信します。
会話は行 114 で割り振り解除されます。
これは、2 番目の例題モジュールです。このアプリケーションのゴールは、最初の例題と同じです。この 2 つの相違は、パフォーマンスの向上のために一部のコードが変更されている点です。
FILESND の場合と同じ SDN を FILESND2 でも使用することができます。
FILESND2.KB のリストは次の通りです。
1 2 -- より効率的な例です。 3 -- 一部の行がコメント化されていることに注意 してください。これらは元の FILESND.KB から 4 -- のもので古いものです。新しい行は (* NEW *) でマーク付けされます。 5 6 KNOWLEDGEBASE FILESND2; 7 8 ROUTINES 9 PROCEDURE DoConversation(VAL Args: List of String); 10 (* sdn, infile *) 11 12 13 PRIVATE 14 15 CONSTANTS 16 CPIC_SUCCESS IS 1; 17 18 TYPES 19 FileRec IS RECORD 20 LineNbr:Integer; 21 Buff:String; 22 END; 23 24 ROUTINES 25 26 FUNCTION RcvData(REF w:WINDOW, VAL Conv: Conversation):INTEGER IS 27 VARIABLES 28 totalBuff :FileRec; 29 dataRcvd :integer; 30 statRcvd :integer; 31 reqTSRcvd :integer; 32 rc :integer; 33 ACTIONS 34 IF (not(Known(w))) THEN 35 WinCreateScrollWindow($DESKTOP,w, 36 $NullHandler, 37 1,1,67,7, 'FileSnd2','', 0, $WinBorder+ $WinTitle+ $WinHScroll+ $WinVScroll+ 38 $WinSysMenu+ $WinResize); 39 END; 40 REPEAT 41 rc := CPICReceive(Conv,'FILEREC.DDF', totalBuff,DataRcvd, StatRcvd,ReqTSRcvd); 42 IF (rc > 0) THEN 43 IF ((StatRcvd = $CPICConfirmReceived)or 44 (StatRcvd=$CPICConfirmSendReceived)) THEN 45 rc := CPICConfirmed(Conv); 46 END; 47 totalBuff.buff := StrTrim (totalBuff.buff); 48 WinWriteLn(w,totalBuff.lineNbr:5&': '&totalBuff.buff); 49 END; 50 UNTIL ((rc <> 1) OR ((StatRcvd = $CPICSendReceived) OR 51 StatRcvd= $CPICConfirmSendReceived))); 52 Exit(rc); 53 END; -- RcvData 54 55 56 --------------------------------------------- 57 -- 説明: 指定されたファイルに読み込み、 指定された SDN を介して指定されたパートナーに 58 -- 各行を CPIC 経由で送信します。 59 --------------------------------------------- 60 PROCEDURE DoConversation(VAL Args: List of String) IS 61 VARIABLES 62 Conv :Conversation; 63 fRec :FileRec; 64 ReqTSRcvd :INTEGER; 65 rc :INTEGER; 66 inf :FILE; 67 w :WINDOW; 68 t1,t2 :TIME; 69 ACTIONS 70 t1 := $NOW; 71 IF (ListLength(Args) < 2) THEN 72 WinMessageBox($DESKTOP,'Oops', $MBOK,'KML FILESND {SDN} {INFILE}'); 73 Exit; 74 END; 75 76 FOpen(inf,Args[2],$Read); 77 78 rc := CPICInitialize(Conv,Args[1]); 79 IF (rc < CPIC_SUCCESS) THEN 80 WinMessageBox($DESKTOP,'CPIC Error', $MBOK,'Init returns '&rc); 81 Exit; 82 END; 83 rc := CPICSetSyncLevel(Conv, $CPICNone); 84 IF (rc < CPIC_SUCCESS) THEN 85 WinMessageBox($DESKTOP,'CPIC Error', $MBOK,'SSL returns '&rc); 86 END; 87 rc := CPICAllocate(Conv); 88 IF (rc < CPIC_SUCCESS) THEN 89 WinMessageBox($DESKTOP,'CPIC Error', $MBOK,'Allc returns '&rc); 90 Exit; 91 END; 92 rc := CPICSetPrepareToReceiveType(Conv, 93 $CPICPrep ToReceiveFlush); 94 IF (rc < CPIC_SUCCESS) THEN 95 WinMessageBox($DESKTOP,'CPIC Error', $MBOK,'SPTR returns '&rc); 96 END; 97 98 fRec.lineNbr := 0; 99 while (FReadLn(inf,fRec.Buff) > 0) do 100(* NEW *) 101-- ファイルの終わりであるかどうかを判別する ことによって、適切な送信タイプを設定する 102-- ことができます。これによって、後から CPICPrepareToReceive の呼び出しを回避する 103-- ことができ、ノード・サービス・システムが パートナーに余分な送信を行わないように 104-- することができます。 105 IF (FEnd(inf)) THEN 106 CPICSetSendType(Conv, $CPICSendAndPrep ToReceive); END; 107 (* END NEW *) 108 fRec.Buff := fRec.Buff & Char(13) & Char(10); -- add CR LF 109 fRec.lineNbr := fRec.lineNbr + 1; 110 rc := CPICSend(Conv, 'FILEREC.DDF', fRec, ReqTSRcvd);
111 IF (rc < CPIC_SUCCESS) THEN 112 WinMessageBox($DESKTOP,'CPIC Error', $MBOK,'Send returns '&rc); ExitLoop; 113 END; 114-- CM/2 によってバッファリングを行います。 もう一方の終端には、送信されたバッファー 115-- の同じ番号がまだ表示されています。CM/2 は 効率のために一部のバッファーをまとめる 116-- ことがあります。 117 (* CPICFlush(Conv); *) 118 119 END; 120 FClose(inf); 121 122 IF (rc = CPIC_SUCCESS) THEN 123-- この通知は最後の送信と一緒に送信される ので、これを実行する必要はありません。 124 CPICPrepareToReceive(Conv); -- パートナーが現在送信できることを示します。-- 125 t2 := $NOW; 126 RcvData(w,Conv); 127 END; 128 129 CPICDeallocate(Conv); 130 WinWriteLn(w,'<<<<<<<<<<<<<<<<<<<<<<<< >>>>>>>>>>>>>>>>>>'); 131 WinWriteLn(w,'Elapsed time for outgoing transmission: '& TimeDif(t2,t1,$SECONDS)&' seconds'); WinWait(w); 132END;
これまで、このアプリケーションをより早く実行させるための努力は行なわれていません。行 105-108 が追加され、行 117 と 124 が除去されました (コメント化)。
FILESND2.KB で行なわれた変更は次の通りです。
CPIC のデータ・バッファリングでは、その使用をためらう点もあります。一番の問題は、ユーザー・アプリケーションがパートナー・アプリケーションと頻繁に "連絡" しないことです。この例の場合、これは問題になりません。ただし、パートナー・アプリケーションによっては、動的に送信する権限が要求可能であることが必要な場合があります。 その場合には、できるだけ頻繁にパートナー・アプリケーションからフラグを受け取るために、バッファーのフラッシュをコントロールすることがベストです。
Tivoli Service Desk 6.0 Developer's Toolkit レガシー API の手引き