Appendix D: xfNetLink Synergy Sample Code
This code sample illustrates how to use RXSUBR and the RX_xxx routines in a Synergy client application. Synclt.dbl calls a subroutine named HELLO on the server.
Client application (synclt.dbl)
The synclt program prompts you for the server name and port number, calls %RX_START_REMOTE to request a remote execution session, and then calls %RXSUBR to make the remote call. It calls the subroutine HELLO on the remote server, which returns the phrase “Hello, <your name>.” Then the program closes down the session with RX_SHUTDOWN_REMOTE. Synclt also includes error handling code that illustrates how to use RX_GET_HALTINFO and RX_GET_ERRINFO.
If you want to try running this program, see the instructions following the code sample. This code is included in the dbl\examples directory in your Synergy/DE distribution.
.main synclt
; Synergy client routine
.define CHAN ,1 ; display channel
.define HELLO_MODULE ,"hello_routine" ; Remote procedure name
; Modify the following define statement for your system
.define NAME ,"Mark" ; Name to display
external function
rc_api ,^val
.include "DBLDIR:rxapi.def"
.define RX_ERR_DEF
record errinforec
.include "DBLDIR:rxerr.def"
.undefine RX_ERR_DEF
.define RX_FATAL_DEF
record haltinforec
.include "DBLDIR:rxerr.def"
.undefine RX_FATAL_DEF
.align
record
netid ,i4 ; network connection ID
status ,i4 ; return status
syserr ,i4 ; returned system error
port ,i4 ; port number
record
aport ,a4
machine ,a80
message ,a30 ; message text
.proc
xcall flags(4020, 1)
open(CHAN, O:C, "TT:")
display(1, "Enter machine: ")
reads(1, machine, done)
display(1, "Enter port number: ")
reads(1, aport, done)
onerror done
port = aport
offerror
status = %RX_START_REMOTE(netid, machine, port) ; Start xfServerPlus
syserr = %syserr
if (status)
begin
writes(1, "Unable to connect to remote session:")
writes(1, " status = " + %string(status))
writes(1, " syserr = " + %string(syserr))
goto done
end
call do_hello ; Call subroutine
done,
if (netid)
xcall RX_SHUTDOWN_REMOTE(netid) ; Stop xfServerPlus
close(CHAN)
stop
do_hello, ; Subroutine to call the remote procedure and handle errors
display(CHAN, $SCR_CLR(SCREEN), $SCR_MOV(2,20))
clear message
;trap fatal and timeout separately, then trap all others
onerror ($ERR_XFHALT) handle_fatal, ($ERR_TIMOUT) handle_timeout, handle_other
xcall rxsubr(netid, HELLO_MODULE, NAME, message)
offerror
display(CHAN, "**** " + %atrim(message) + " ****")
return
; Error handling routines
handle_fatal,
offerror
writes(CHAN, "Fatal error trapped")
xcall RX_GET_HALTINFO(netid, haltinforec)
call disp_halt
goto done
handle_timeout,
offerror
writes(CHAN, "Timeout error trapped")
xcall RX_GET_ERRINFO(netid, errinforec)
call disp_err
goto done
handle_other,
offerror
writes(CHAN, "Error trapped")
xcall RX_GET_ERRINFO(netid, errinforec)
call disp_err
goto done
disp_halt,
writes(CHAN, "Subroutine: " + %atrim(haltinforec.rx_fatalerror.subroutine_name))
writes(CHAN, "Error line #: " + %string(haltinforec.rx_fatalerror.error_line_number))
writes(CHAN, "Error #: " + %string(haltinforec.rx_fatalerror.error_num))
writes(CHAN, "System Error #: " + %string(haltinforec.rx_fatalerror.error_num))
writes(CHAN, "Program name: " + %atrim(haltinforec.rx_fatalerror.prog_name))
writes(CHAN, "Error text: " + %atrim(haltinforec.rx_fatalerror.error_text))
return
disp_err,
writes(CHAN, "Method ID: " + %atrim(errinforec.rx_stderror.method_id))
writes(CHAN, "# of errors: " + %string(errinforec.rx_stderror.num_of_errors))
writes(CHAN, "Error #: " + %string(errinforec.rx_stderror.error_num))
writes(CHAN, "Description: " + %atrim(errinforec.rx_stderror.description))
writes(CHAN, "Clarification: " + %atrim(errinforec.rx_stderror.clarifying_desc))
return
.end
Server-side code (HELLO subroutine)
The HELLO subroutine is the remote routine (on the server) called by synclt. This code is included in the dbl\examples directory in your Synergy/DE distribution.
.subroutine hello ;Arguments a_name ,a a_message ,a .define HELLO ,"Hello " .define NONAME ,"No name passed " .proc if (^passed(a_name)) then a_message = %atrim(HELLO + a_name) else a_message = NONAME xreturn .end
Running the hello program
| 1. | Create an ELB or shared image named hello.elb containing the HELLO subroutine. Put the ELB on your server machine (the machine that xfServerPlus is running on). |
| 2. | Start the Method Definition Utility and create a method in the SMC for the HELLO subroutine. (See Using the MDU to define Synergy methods for instructions.) Include the following information in your MDU entry: |
Method name = hello_routine
Method ID = hello_routine (this is copied from the method name)
Routine name = hello
ELB/shared image name = DBLDIR:hello (change the logical if necessary)
Return type = No return value
The subroutine has two parameters, name and message. Set them up as follows:
Parameter name = name
Data type = Alpha
Length = 20
Data passed = In
Pass by = Descriptor
Required
Parameter name = message
Data type = Alpha
Length = 30
Data passed = In/Out
Pass by = Descriptor
Required
| 3. | If xfServerPlus is not already running, start it on the server machine. See one of the following for details: |
| 4. | Put synclt.dbl on the client machine and edit the NAME identifier. |
| 5. | Compile and link synclt.dbl. |
| 6. | Run synclt.dbr. You’ll be prompted to enter the machine name and port where xfServerPlus is running. |
