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
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. |