/* client_validateCustomerAsync.p */
/*******************************************************************/
DEFINE VARIABLE hWebService AS HANDLE NO-UNDO.
DEFINE VARIABLE hPortType AS HANDLE NO-UNDO.
DEFINE VARIABLE cResponse AS CHARACTER NO-UNDO.
DEFINE VARIABLE li AS INTEGER NO-UNDO.
DEFINE VARIABLE retValue AS CHARACTER INITIAL "OK" NO-UNDO.
DEFINE VARIABLE err AS LOGICAL NO-UNDO.
DEFINE VARIABLE result AS CHARACTER NO-UNDO.
DEFINE VARIABLE har1 AS HANDLE EXTENT 100 NO-UNDO.
DEFINE VARIABLE iCustNums AS INTEGER EXTENT 100 NO-UNDO.
DEFINE VARIABLE cCustNames AS CHARACTER EXTENT 100 NO-UNDO.
DEFINE VARIABLE j AS INTEGER NO-UNDO.
DEFINE VARIABLE iMinCust AS INTEGER INITIAL 80 NO-UNDO.
DEFINE VARIABLE iMaxCust AS INTEGER INITIAL 90 NO-UNDO.
/*******************************************************************/
CREATE SERVER hWebService.
ETIME(true).
li = MTIME.
hWebService:CONNECT("-WSDL 'http://rs:25011/wsa/wsa1/wsdl?targetURI=urn:prgs:DocLiteral'
-Service WSTKDocLiteralService
-Port WSTKDocLiteralObj").
IF NOT hWebService:CONNECTED() THEN DO:
MESSAGE "SERVER NOT CONNECTED" VIEW-AS ALERT-BOX.
retValue = "ERROR".
END.
RUN WSTKDocLiteralObj SET hPortType ON SERVER hWebService NO-ERROR.
IF ERROR-STATUS:ERROR THEN DO:
MESSAGE "Failed to create hPortType" VIEW-AS ALERT-BOX.
retValue = "ERROR".
END.
DO li = iMinCust TO iMaxCust:
/*the result parameter is mapped on RETURN-VALUE*/
RUN getCustomerName IN hPortType ASYNCHRONOUS SET har1[li]
EVENT-PROCEDURE "ValidateCustomerResponseHandler" (INPUT li,
OUTPUT result, OUTPUT cResponse) NO-ERROR.
RUN ErrorInfo (OUTPUT err).
iCustNums[li] = li.
PROCESS EVENTS.
END.
/*memory cleanup*/
DO WHILE (hWebService:ASYNC-REQUEST-COUNT > 0):
PROCESS EVENTS.
PAUSE 5.
MESSAGE
"ASYNC-REQUEST-COUNT: " hWebService:ASYNC-REQUEST-COUNT
VIEW-AS ALERT-BOX.
END.
/*disp result*/
DO j = iMinCust TO iMaxCust:
MESSAGE iCustNums[j] " = " cCustNames[j]
VIEW-AS ALERT-BOX.
END.
DELETE PROCEDURE hPortType.
hWebService:DISCONNECT().
DELETE OBJECT hWebService.
RETURN retValue.
/*******************************************************************/
PROCEDURE ValidateCustomerResponseHandler:
DEFINE INPUT PARAMETER result AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER cCustName AS CHARACTER NO-UNDO.
DO j = iMinCust TO iMaxCust:
IF SELF = har1[j] THEN DO:
IF cCustName = ? THEN cCustNames[j] = "not found".
ELSE cCustNames[j] = cCustName.
LEAVE.
END.
END.
END.
/*******************************************************************/
PROCEDURE ErrorInfo: /*1*/
DEFINE OUTPUT PARAMETER errorfound AS LOGICAL INITIAL FALSE.
DEFINE VARIABLE i AS INTEGER NO-UNDO.
DEFINE VARIABLE hSOAPFault AS HANDLE NO-UNDO.
DEFINE VARIABLE hSOAPFaultDetail AS HANDLE NO-UNDO.
DEFINE VARIABLE HeaderXML AS LONGCHAR VIEW-AS EDITOR SIZE 70 BY 15 LARGE.
IF ERROR-STATUS:NUM-MESSAGES > 0 THEN DO:
errorfound = TRUE.
DO i = 1 TO ERROR-STATUS:NUM-MESSAGES:
MESSAGE ERROR-STATUS:GET-MESSAGE(i) VIEW-AS ALERT-BOX.
END.
/*2*/
IF VALID-HANDLE(ERROR-STATUS:ERROR-OBJECT-DETAIL) THEN DO:
hSOAPFault = ERROR-STATUS:ERROR-OBJECT-DETAIL.
MESSAGE
"Fault Code: " hSOAPFault:SOAP-FAULT-CODE SKIP
"Fault String: " hSOAPFault:SOAP-FAULT-STRING SKIP
"Fault Actor: " hSOAPFault:SOAP-FAULT-ACTOR SKIP
"Error Type: " hSOAPFault:TYPE VIEW-AS ALERT-BOX.
/*3*/
IF VALID-HANDLE(hSOAPFault:SOAP-FAULT-DETAIL) THEN DO:
hSOAPFaultDetail = hSOAPFault:SOAP-FAULT-DETAIL.
MESSAGE "Error Type: " hSOAPFaultDetail:TYPE
VIEW-AS ALERT-BOX.
HeaderXML = hSOAPFaultDetail:GET-SERIALIZED().
DISPLAY HeaderXML LABEL "Serialized SOAP fault detail"
WITH FRAME a.
END.
END.
END.
END PROCEDURE.
/*******************************************************************/
What about using an AppServer to do the async bit? Your webspeed can run the code below, the appserver can run webservice call.
DEF VAR hAppServer AS HANDLE NO-UNDO.
DEF VAR hProc AS HANDLE NO-UNDO.
CREATE SERVER hAppServer.
hAppServer:CONNECT("-H localhost") NO-ERROR. /* Assumes an appserver supporting the default service */
RUN yourprocedure.p ON SERVER hAppServer ASYNCHRONOUS SET hProc (INPUT yourparameters).
Does this actual work or is it just theory? I keep thinking it will cause resource issues over time as none of the handle(s) will get not get tidy up (unless they were stored somewhere and clean up later)???
DEFINE VARIABLE vhCurServer AS HANDLE NO-UNDO.
vhCurServer = SESSION:FIRST-SERVER.
/*Clean up any async procedures running on the app server
NB: only if not open server sockets*/
IF NOT VALID-HANDLE(SESSION:FIRST-SERVER-SOCKET) THEN
DO WHILE VALID-HANDLE( vhCurServer ) :
IF vhCurServer:ASYNC-REQUEST-COUNT = 0 THEN
DO:
IF vhCurServer:CONNECTED() THEN
vhCurServer:DISCONNECT().
DELETE OBJECT vhCurServer.
vhCurServer = SESSION:FIRST-SERVER.
END.
ELSE
vhCurServer = vhCurServer:NEXT-SIBLING.
END.