Tools

21. Windows にメッセージを送る SNDWINMSG

System i から Windowsにメッセージを送信したい場合があり、これは結構重要な機能となる場合がある。
クライアント/サーバー・モデルの適用業務を運用する場合にサーバー(System i)側で障害が
発生したり、重要なメッセージを送信したい場合である。
例えばC/Sモデルの適用業務において通信障害が発生したとすると、そのことをクライアントに
伝える手段がない。なにしろ伝えようにも通信が切断されているからである。
Webアプリケーションでも同じことである。
Webアプリケーションでもブラウザをクライアント・モジュールとする広義の意味でのC/Sモデルである
と言えるからである。
TCP/IP やHTTPプロトコルが終了したしまったのでは、クライアントにエラーがサーバー側で発生
していることを伝達する手段すらない。
開発者やシステム担当者であればサーバー側の様子を直ちに調査するであろうが、エンド・
ユーザーでは「画面がフリーズした」として決してサーバー側を調査するようなことはない。
クライアントが動作しないというクレームだけが管理者に送られてくるだけである。
また、別件であるが ある人は Web化した適用業務では 5250環境と違って、SNDBRKMSG
(中断メッセージ) だけは処理不可能であると言った。
これはなるほど、Web適用業務では必ず SUBMIT しないとサーバー(System i)からの応答を
入手することができないので 5250エミュレータ画面で何も操作していないのにいきなり
「BACKUPを取りますので業務を中止してください」などの *BREAKメッセージを受け取ることが
できないのである。
しかし、もし不定期に サーバー側からクライアント、つまり Windows へメッセージを送ることが
できたらこの問題は解決する。
読者は System i の NetServer (ネット・サーバー) をご存知だろうか ?
これは System i の IFS などを共有フォルダーとして Windowsエクスプローラに公開を許可する
ものである。
つまり NetServer 自身が NetBios を使用しているのである。
さらに NetServer 自身のいくつかの API が IBM によって公開されている。
そして、この利用方法が QUSRTOOL に収められているのである。

■ Windows にメッセージを送信する SNDWINMSG

筆者は QUSRTOOL に収録されているソースにいくつかの改訂を加えたので結果をここに紹介する。

【 コマンド SNDWINMSG 】
              CMD        PROMPT('WINDOWS メッセージの送信 ')           
0002.00              PARM       KWD(MSG) TYPE(*CHAR) LEN(128) +               
0003.00                           PROMPT(' メッセージ・テキスト ')            
0004.00              PARM       KWD(TONETID) TYPE(E1) MIN(0) MAX(20) +        
0005.00                           PROMPT('Network ID')                        
0006.00  E1:         ELEM       TYPE(*CHAR) LEN(15) DFT('192.168.1.1') +      
0007.00                           MIN(0) MAX(1) PROMPT(' 宛先 IP アドレス ')  
0008.00              ELEM       TYPE(*CHAR) LEN(15) MIN(0) MAX(1) DFT(*NONE) +
0009.00                           SPCVAL((*NONE)) +                           
0010.00                           PROMPT(' システム名 ')
【 CLP SNDWINMSG 】
0001.00              PGM        PARM(&MSGTXT &TONETID)                          
0002.00 /*---------------------------------------------------------*/           
0003.00 /*   SNDWINMSG :  WINDOWS へのメッセージの送信             */           
0004.00 /*---------------------------------------------------------*/           
0005.00              /*-------------------------------------------------------- 
0006.00              /*  Declares needed for this program                       
0007.00              /*-------------------------------------------------------- 
0008.00              DCL        VAR(&MSGTXT)     TYPE(*CHAR) LEN(128)           
0009.00              DCL        VAR(&TONETID)    TYPE(*CHAR) LEN(700)           
0010.00              DCL        VAR(&NETSYSNAME) TYPE(*CHAR) LEN(30)            
0011.00              DCL        VAR(&NETWORK)    TYPE(*CHAR) LEN(15)            
0012.00              DCL        VAR(&SYSTEM)     TYPE(*CHAR) LEN(15)            
0013.00              DCL        VAR(&INDEX1)     TYPE(*DEC)  LEN(4) VALUE(1)    
0014.00              DCL        VAR(&INDEX2)     TYPE(*DEC)  LEN(4) VALUE(1)    
0015.00              DCL        VAR(&NBRTOSEND)  TYPE(*DEC)  LEN(4)             
0016.00              DCL        VAR(&NEXTOFFLOC) TYPE(*DEC)  LEN(4)             
0017.00              DCL        VAR(&NEXTOFFSET) TYPE(*DEC)  LEN(4)             
0018.00              DCL        VAR(&IPADR) TYPE(*CHAR) LEN(15)                 
0019.00              DCL        VAR(&OS400) TYPE(*CHAR) LEN(6)                  
0020.00              DCL        VAR(&TYPE) TYPE(*CHAR) LEN(1)                   
0021.00              DCL        VAR(&RTNVALUE) TYPE(*CHAR) LEN(256)             
0022.00              DCL        VAR(&MSG) TYPE(*CHAR) LEN(80)                   
0023.00                                                                         
0024.00              /*-------------------------------------------------------- 
0025.00              /*  Constants needed for this program                      
0026.00              /*-------------------------------------------------------- 
0027.00              DCL        VAR(&BLANK)     TYPE(*CHAR) LEN(1) VALUE(' ')   
0028.00              DCL        VAR(&HEXZERO)   TYPE(*CHAR) LEN(1) VALUE(X'00') 
0029.00                                                                         
0030.00                                                                         
0031.00              /*-------------------------------------------------------- 
0032.00              /*   Start of the executable code for the program.         
0033.00              /*-------------------------------------------------------- 
0034.00              MONMSG     MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))         
0035.00                                                                         
0036.00              RTVJOBA    TYPE(&TYPE)                                     
0037.00              RTVDTAARA  DTAARA(QGPL/QSS1MRI (1 6)) RTNVAR(&OS400)       
0038.00              IF         COND(&OS400 *LT 'V5R1M0') THEN(DO)              
0039.00              CHGVAR     VAR(&MSG) +                                     
0040.00                           VALUE('SNDWINMSG の実行は V5R1M0 以上が必 +   
0041.00                            要です。 ')                                  
0042.00              IF         COND(&TYPE *EQ '0') THEN(DO)                   
0043.00              SNDPGMMSG  MSG(&MSG) TOMSGQ(*SYSOPR) MSGTYPE(*COMP)       
0044.00              ENDDO                                                     
0045.00              ELSE       CMD(DO)                                        
0046.00              SNDPGMMSG  MSG(&MSG) TOMSGQ(*TOPGMQ) MSGTYPE(*DIAG)       
0047.00              ENDDO                                                     
0048.00              RETURN                                                    
0049.00              ENDDO                                                     
0050.00              /*--------------------------------------------------------
0051.00              /*  Break the TOUSER parameter into the network name and  
0052.00              /*  system name parts. Only move the non-blank part of    
0053.00              /*  the network and system names.                         
0054.00              /*--------------------------------------------------------
0055.00              CHGVAR &NBRTOSEND %BINARY(&TONETID 1 2)                   
0056.00              IF (&NBRTOSEND = 0) THEN(GOTO SENDALL)                    
0057.00              CHGVAR &NEXTOFFLOC 3                                      
0058.00  LOOP1:      IF (&INDEX1 > &NBRTOSEND) THEN(GOTO SENDDONE)             
0059.00                CHGVAR &NEXTOFFSET %BINARY(&TONETID &NEXTOFFLOC 2)      
0060.00                CHGVAR &NEXTOFFSET (&NEXTOFFSET+3)                      
0061.00                CHGVAR &NETSYSNAME %SST(&TONETID &NEXTOFFSET 30)        
0062.00                CHGVAR &INDEX2 1                                        
0063.00  LOOP2:        IF (&INDEX2 > 30) THEN(GOTO ENDLOOP)                    
0064.00                  IF (%SST(&NETSYSNAME &INDEX2 1) = &BLANK) +           
0065.00                    THEN(CHGVAR %SST(&NETSYSNAME &INDEX2 1) &HEXZERO)   
0066.00                  CHGVAR &INDEX2 (&INDEX2+1)                            
0067.00                  GOTO LOOP2                                            
0068.00  ENDLOOP:      CHGVAR &IPADR %SST(&NETSYSNAME 1 15)                    
0069.00                CHGVAR &SYSTEM  %SST(&NETSYSNAME 16 15)                 
0070.00                                                                        
0071.00              IF         COND(&IPADR *EQ '*IPADR') THEN(DO)             
0072.00              ASNET.COM/GETENV ENV(REMOTE_ADDR) VALUE(&RTNVALUE)        
0073.00              CHGVAR     VAR(&IPADR) VALUE(%SST(&RTNVALUE 1 15))        
0074.00              ENDDO                                                     
0075.00              ADDENVVAR  ENVVAR(REMOTE_ADDR) VALUE(&IPADR)              
0076.00              MONMSG     MSGID(CPFA980) EXEC(DO)                        
0077.00              CHGENVVAR  ENVVAR(REMOTE_ADDR) VALUE(&IPADR)              
0078.00              ENDDO                                                     
0079.00              CHGVAR     VAR(&NETWORK) VALUE(&IPADR)                    
0080.00              CALL       PGM(ASNET.COM/RTVWSID) PARM(&NETWORK)          
0081.00              IF         COND(%SST(&NETWORK 1 5) *EQ '*NONE') THEN(DO)  
0082.00              SNDPGMMSG  MSG('SNDWINMSG [' *CAT &IPADR *TCAT '] ' +     
0083.00                         *CAT &MSG) TOMSGQ(*SYSOPR) MSGTYPE(*COMP)      
0084.00              RETURN                                                     
0085.00              ENDDO                                                      
0086.00                IF (%SST(&SYSTEM 1 5) = '*NONE') +                       
0087.00                  THEN(CALL  PGM(QZLSMAINT) PARM('30' &NETWORK &MSGTXT)) 
0088.00                  ELSE (CALL  PGM(QZLSMAINT) PARM('37' &NETWORK &SYSTEM  
0089.00                CHGVAR &NEXTOFFLOC (&NEXTOFFLOC+2)                       
0090.00                CHGVAR &INDEX1 (&INDEX1+1)                               
0091.00                GOTO LOOP1                                               
0092.00  SENDDONE:                                                              
0093.00              IF         COND(&TYPE *EQ '1') THEN(DO) /*  対話式  */     
0094.00              CHGVAR     VAR(&MSG) VALUE(' メッセージを ' *CAT +         
0095.00                           &IPADR *TCAT ' に送信しました。 ')            
0096.00              GOTO       SNDMSG                                          
0097.00              ENDDO      /*  対話式  */                                  
0098.00              RETURN                                                     
0099.00                                                                         
0100.00  SENDALL:    CALL PGM(QZLSMAINT) PARM('30' *ALL &MSGTXT)                
0101.00              RETURN                                                     
0102.00                                                                         
0103.00  ERROR:      RCVMSG     MSGTYPE(*LAST) RMV(*NO) MSG(&MSG)               
0104.00  SNDMSG:                                                                
0105.00              IF         COND(&TYPE *EQ '0') THEN(DO)              
0106.00              SNDPGMMSG  MSG(&MSG) TOMSGQ(*SYSOPR) MSGTYPE(*COMP)  
0107.00              ENDDO                                                
0108.00              ELSE       CMD(DO)                                   
0109.00              SNDPGMMSG  MSG(&MSG) TOMSGQ(*TOPGMQ) MSGTYPE(*DIAG)  
0110.00              ENDDO                                                
0111.00              ENDPGM
【 解説 】

EnterpriseServer Ver5.0 では、このSNDWINMSG を使ってサーバー側の障害が発生したときは
直ちにクライアントへエラー・メッセージが表示される仕組みとなっている。
またユーザーでも、このSNDWINMSG をユーザーの適用業務へ組み込むことができるように公開も
されている。