Previous Introduction

Chapter 2: Client/Server Binding

This chapter explains how the client/server binding works and then describes how to connect your user programs to the generic client/server modules.

If you want to use the client/server binding with a Dialog System application, please see the chapter Using the Client/Server Binding in the online book, Dialog System User Guide as this includes code examples which are specific to Dialog System.

2.1 Introduction

The client/server binding is a simple, light-weight, Remote Procedure Call (RPC) mechanism, for use with 25 clients or less, that enables you to implement a client/server architecture without having to worry about communications programming. The AAI (Application to Application Interface) component of the client/server binding is provided for users wanting to migrate applications that require more than 25 clients.

The client/server binding is included as part of NetExpress for use in applications which do not require an extensive, fault tolerant middleware solution. The AAI client component is included with NetExpress for migration to a more comprehensive middleware product for applications requiring fault tolerance, rollback and recovery options. You may want to consider programming directly to the AAI interface before starting your development project. More information regarding this API is available in the AAI Server component. The AAI Server components are sold separately. Please contact your Sales Representative for more information.

You should ensure that the capabilities and performance provided by the client/server binding are adequate for your business needs. For many applications, this is the case and the client/server binding offers a solution which is both easy to implement and extremely cost-effective to deploy.

The client/server binding removes the requirement for you to include communications code in your application by providing two modules called mfclient and mfserver. These are generic modules which can be used to drive any application.

Based on information contained in a configuration file, these modules manage the communications link and the transfer of data and are able to interact with user-defined programs at each end of the link. The mfclient module is called by a user-written client program (which may, for example, handle the user interface) while mfserver calls a user-written server program (which may, for example, handle data access and business logic).

The user-written client and server programs use the copyfile mfclisrv.cpy to interact with the generic client/server modules.

Supplied with NetExpress is an example application which demonstrates how the client/server binding can be used. This example application, which transfers file data between a client and a server, is installed in the sub-directory Csbind in your NetExpress \demo directory.

2.2 How the Client/Server Binding Works

The client/server binding works by having a non­dedicated copy of mfserver running on the server tier; this copy of mfserver communicates with any and all clients using an agreed server name. The mfserver module can be run using its built-in defaults, as its only function is to receive requests from the client to establish or terminate a connection.

The flow of information is explained below (the program files from the demonstration application Csbind are used as example client and server programs):

  1. The user-written client program (netxcli.cbl) performs any application initialization code, prompts the user for the name of a file, checks that the file exists and then calls mfclient.

  2. The first time mfclient is called, it reads configuration information from the configuration file netxdem.cfg.

  3. mfserver receives the connection request.

  4. mfserver spawns a secondary server for each client. The server name is internally generated, based on the name of the initial server with a numeric ID added (for example, mfserver01). Alternatively, you can specify a name in the configuration file.

  5. mfserver sends the secondary server name (mfserver01) back to mfclient and terminates the conversation.

  6. mfclient connects with the secondary server (mfserver01), passing parameters obtained from the configuration file via the LNK-PARAM-BLOCK (see the section, The Client/Server Binding Copyfile).

  7. mfserver01 calls the user-written server program (netxserv.cbl), passing the parameters received from mfclient via the Linkage Section.

  8. The first time the user-written server program (netxserv.cbl) is called, it performs any application initialization code, and exits the program. Control is returned to mfserver01.

  9. mfserver01 returns control to mfclient.

  10. mfclient ensures contact has been established and returns control to the user-written client program (netxcli.cbl).

  11. The client program (netxcli.cbl) opens the file specified by the user, reads a record from it and calls mfclient to pass the data via the Linkage Section.

  12. mfclient passes the data to mfserver01 via its internal buffer.

  13. mfserver01 passes the data to the user server program (netxserv.cbl) which creates a file and writes the record to it.

    This read record/write record loop continues until the user-written client program (netxcli.cbl) reaches end-of-file, at which point it closes the file and sends an indication that it is about to terminate to the server. The server responds by sending the name of the directory into which the file was copied.

  14. The client program (netxcli.cbl) displays the name of the file which has been created on the server and calls mfclient with LNK-CNTRL-FLAG set to "client-ending" and then terminates.

2.3 How to Use the Client/Server Binding

To use the client/server binding in your application, you need to:

Each of these steps is explained in more detail below.

2.4 The Client/Server Binding Copyfile

The mfclient and mfserver modules pass information to each other via the parameter block, LNK-PARAM-BLOCK, defined in the copyfile mfclisrv.cpy. The modules also use this parameter block to pass information to any user programs they have been requested to call. The mfclisrv.cpy copyfile must be included in any of your COBOL programs which use the mfclient and mfserver modules.

The mfclisrv.cpy copyfile is installed in the SOURCE directory of your NetExpress base installation directory.

2.5 The Client/Server Binding Configuration File

The client/server binding configuration file controls the behaviour of the mfclient and mfserver modules as well as the communications link.

The client/server binding configuration file is an ASCII text file which must have a .cfg extension. If you do not supply a configuration filename yourself, the default configuration filename, mfclisrv.cfg is used.

You can have separate configuration files for each application or you can supply multiple entries in a single file. If you are using multiple entries, each application must have its own tag entered in the file, followed by the list of parameters for that application. You must then specify this tag-name in your client program using the LNK-TAGNAME field in the LNK-PARAM-BLOCK parameter block. This technique can be used to reduce your command line length by specifying your multiple entries in the default configuration file, mfclisrv.cfg.

If your client/server application is incorrectly set up, any invalid entries found in the configuration file will cause the programs reading them to terminate with a message displayed on the screen detailing the invalid entries.

These errors are also logged in the mfclisrv.log file, which is created in the current directory, or in the directory indicated by the MFLOGDIR environment variable. This enables a server which is not directly connected to a terminal to log messages.

2.5.1 Configuration File Parameters

Listed below are all of the possible entries for the mfclisrv.cfg configuration file. Entries are listed in alphabetical order. Any entries which you do not specify in your configuration file assume the default values.

aaiservice=name PIC X(128) [default: MFCLISRV]

Name of the AAI Service to connect to. This is the logical service name entry in the AAI administration system.

cblksize=nnnn PIC X(4) COMP-X [default: 0]

Size of Dialog System control block. For use with Dialog System only.

clierrprog=name PIC X(128) [default: none]

Name of the program which will handle communication errors instead of mfclient. You can enter a name of SAME to use the calling program to handle any mfclient errors.

commsapi=api PIC X(4) [default: CCI]

The communications API; valid values are CCI, AAI or NONE. The special entry NONE can be used when developing two tier applications to allow testing to be undertaken on a single PC without any communications products. Data is passed directly between mfclient and the user-written server program, bypassing mfserver and the communications requirement.

Note: You cannot use this option if an existing application is being deployed as the user-written server program.

compress=nnn PIC 9(3) [default: 000]

The number of the compression routine to be used, for example, 001 indicates that routine CBLDC001 will be used. Setting this parameter to 0 indicates that data compression will not be used.

dblksize=nnnn PIC X(4) COMP-X [default: 0]

The size of the user data area used to pass data between the user-written client and server programs. For Dialog System applications this will be the size of the Dialog System datablock.

Warning: Unpredictable results can occur if this entry is less than the actual size of the data area being used.

eblksize=nnnn PIC X(4) COMP-X [default: 0]

The size of the optional Dialog System Event block.

machinename=name PIC X(34)

The name of the machine on which the server specified in the servername entry is located. This prevents the system searching for the first match of the defined name.

maxtrans=nn PIC 99 [default: 0]

The maximum transfer package size in Kilobytes. Valid values are 1 - 62. If the total buffer size exceeds this amount, the system will make multiple transfers of maxtrans size until the total buffer is transferred.

midconfig=filename PIC X(128) [default: none]

The name of the configuration file to be used by mfclient when called by mfserver as part of a cross-tier solution. Specifying this entry causes mfserver to act as a router passing data to a local mfclient module. This mfclient module uses this configuration file to locate and communicate with another server. This allows protocols and communications APIs to be changed across the machines used.

protocol=protocol PIC X(8) [default: CCITC32]

The CCI protocol to be used. This entry is only applicable if commsapi is set to CCI. You can specify any of the supported CCI protocols: Novell IPX (enter CCIIX32), NetBEUI (enter CCINB32), Dynamic Data Exchange (enter CCIDE32) or TCP/IP (enter CCITC32). Note that if commsapi is set to CCI (which is the default) and you do not specify a protocol, the client/server binding defaults to TCP/IP (CCITC32).

scrntype=type PIC X(4) [default: none]

If, for example, the user program supports both GUI and character interfaces this entry can be used as an indicator to tell the client program which type of interface is being used. scrntype is not validated by the client/server binding modules.

servername=server PIC X(14) [default: MFCLISRV]

The servername to be used for communications.

setenv=name value PIC X(148) [default: none]

Environment variable to be set on the server before the execution of any server programs. The format is:

variable name PIC X(20)

variable value PIC X(128)

The name and value fields must be separated by at least one space character. Up to nine setenv entries can be specified.

srvanim=x PIC X(16) [default: N]

Y or N. Setting this parameter to Y enables animation of the user programs running on the server. This means that mfserver does not have to be stopped and restarted with COBSW=+A as this is set up dynamically.

On UNIX systems only, you can specify a value of x,filename to enable cross-session animation of your programs. See the section Animating your Applications for more details.

srverrprog=name PIC X(128) [default: none]

Name of the program which will handle communication errors instead of mfserver. You can enter a name of SAME to use the name set in the srvprog entry for mfserver errors.

srvprog=name PIC X(128)

Name of the user-written program to be called by mfserver.

srvtier=name PIC X(128) [default: mfserver]

The name of the server tier program. When specified, it indicates that mfserver will be called by this program.

subserver=base-name PIC X(14) [default: none]

The base-name to be used for communicating with sub-server processes. The default server-name is mfclisrv and sub-servers are named mfclisrv00001,mfclisrv00002 and so on. Setting this parameter to newserv results in sub-server names of newserv00001, newserv00002 and so on. This enables application-specific sub-server names to be used without changing the base server name.

timeout=nnnn PIC X(4) COMP-5 [default: 120 secs)

You can use this parameter to override the system timeout default. The timeout period is specified in 1/10 (tenths) of a second. Previously issued calls retain the timeout period that was in use when they were originally invoked.

ublksize=nnnn PIC X(4) COMP-X [default: 0]

Size of optional user data block.

useraudit=x PIC X [default: N]

Y or N. Setting this parameter to Y results in the logging of client connect and disconnect details. When set, the following details are logged by both client and server: date, time, connect/disconnect indicator, servername, machinename, and protocol. These details are written to the system log file, see Creating Audit Trails and System Log File below.

2.5.2 Minimum Required Configuration File Entries

The minimum entries required in the configuration file varies according to:

You must always have the following entries:

dblksize The size of the user data area used for data transfer
srvprog The name of the program that mfserver calls to perform the server-side processing. This is the user program on the server machine (that is,the COBOL program performing data access and business logic).

When running multiple servers, you must supply the name of the server to be used via the servername entry.

If you are not using CCI, you must set the commsapi entry and if you are using CCI, but not TCP/IP, you must set the protocol entry.

Any configuration file entries which are unset assume the specified default values.

2.5.3 Locating the Configuration File

Your configuration file can be located where it best suits you. The mfclient and mfserver programs attempt to locate the configuration file as follows:

  1. They look for the MFCSCFG environment variable and use the supplied filename if one is specified.

  2. They examine the command line and use any filename defined there in preference to that supplied via the MFCSCFG environment variable.

  3. If neither of the above yields a filename, the default filename mfclisrv.cfg is assumed and searched for in the current directory.

  4. If mfclisrv.cfg is not found, the default settings for the configuration entries are used.

In each case a full pathname of up to 128 characters can be used to identify the location of the configuration file.

2.6 Connecting Your Client Program to mfclient

The mfclient and mfserver modules pass information to each other via a parameter block described in the mfclisrv.cpy copyfile. The modules use the same parameter block, LNK-PARAM-BLOCK, to pass information to user programs.

You must add code to your program, as in the example below, to enable it to pass parameters to mfclient.

$SET ANS85

 WORKING-STORAGE SECTION. ......

*--- mfclisrv.cpy must be included in the working storage
*--- section of the client program and in the linkage
*--- section of the server program.

 COPY "MFCLISRV.CPY".

 LINKAGE SECTION. ......

*--- Input-Rec is the area used for transfering data
*--- between the user client and the server programs.
*--- The size of this data area is defined by the user
*--- in the Client/Server Binding configuration file
*--- which is read by the mfclient module. mfclient
*--- sets up the required memory for this area and
*--- returns a pointer to this area back to the user
*--- client program (see below).

 01 INPUT-REC               PIC X(32767)

 PROCEDURE DIVISION.

 CLIENT-CONTROL SECTION.

     PERFORM UNTIL END-CONNECTION

*--- lnk-client holds the name "mfclient".
*--- The first time through we initialize mfclient and establish
*--- contact with the server.

        CALL LNK-CLIENT USING LNK-PARAM-BLOCK

        EVALUATE TRUE

*--- Make the user data area (Input-Rec) accessible by assigning
*--- the address returned by mfclient.

           WHEN START-CONNECTION
              SET ADDRESS OF INPUT-REC TO LNK-DBLOCK-PTR

           WHEN END-CONNECTION
              EXIT PERFORM

           WHEN OTHER

*--- Perform your application client logic. For example, display
*--- and accept user interface data.

              ......

         END-EVALUATE

*--- Set a user defined flag (eg. EXIT-FLG-TRUE) to indicate
*--- that client processing has terminated. For example, you
*--- may have clicked on the EXIT push button on your application
*--- interface.

         IF EXIT-FLG-TRUE
            SET CLIENT-ENDING TO TRUE
         END-IF

     END-PERFORM.

 CLIENT-CONTROL-END.
     STOP RUN.

If you want to control the number of clients running an application, or you choose to handle error message displays yourself, you will need to add code similar to the following to your program's initial EVALUATE statement:

           WHEN TOO-MANY-CLIENTS
              PERFORM OVER-CLIENT-LIMIT

           WHEN COMMS-ERROR
              PERFORM SHOW-ERROR

           ......

 OVER-CLIENT-LIMIT SECTION.
     DISPLAY SPACES AT 0101 WITH BACKGROUND-COLOR 7
        "MAXIMUM NUMBER OF CLIENTS EXCEEDED - SESSION ENDED"
        AT 1012 WITH FOREGROUND-COLOR 4
     SET EXIT-FLG-TRUE
     SET CLIENT-ENDING TO TRUE
     EXIT.

 SHOW-ERROR SECTION.
     DISPLAY LNK-ERROR-LOC AT 2201
     DISPLAY LNK-ERROR-MSG AT 2301 WITH SIZE LNK-ERROR-MSG-LEN.
     EXIT.

If asynchronous requests are to be handled, you must add to the EVALUATE statement additional code similar to the following:


Note: ASYNC-REQUEST is not necessary if you are using AAI.


WHEN START-CONNECTION
   PERFORM GET-USER-INPUT
   IF MAKE-ASYNC-REQUEST <* user asynchronous option
      SET ASYNC-REQUEST TO TRUE
   END-IF

WHEN ASYNC-OK
   SET TEST-ASYNC-RESULT TO TRUE
   PERFORM DELAY-LOOP

WHEN ASYNC-INCOMPLETE
   DISPLAY "REQUEST STILL BEING PROCESSED" AT 1010
   PERFORM DELAY-LOOP
   SET TEST-ASYNC-RESULT TO TRUE

WHEN RESULT-OK
   DISPLAY "REQUEST-COMPLETED " AT 1010
   PERFORM GET-USER-INPUT

WHEN ASYNC-NOT-STARTED
WHEN ASYNC-FAILED
   DISPLAY "ASYNCHRONOUS REQUEST FAILURE " AT 1010
   PERFORM SHOW-ERROR
   PERFORM GET-USER-INPUT

WHEN COMMS-ERROR
   PERFORM SHOW-ERROR

2.7 Connecting Your Server Program to mfserver

The mfclient and mfserver modules pass information to each other via a parameter block described in the mfclisrv.cpy copyfile. The modules use the same parameter block to pass information to any user programs.

Your server program must include the copyfile, mfclisrv.cpy in the Linkage Section. You must also modify the Procedure Division header to include the parameter block, LNK-PARAM-BLOCK, which is used to pass parameters from mfserver.

This is shown below in the example server code:

 LINKAGE SECTION.

 01 INPUT-REC                 PIC X(32767).

 COPY "MFCLISRV.CPY".*--- lnk-param-block is the record definition in mfclisrv.cpy

 PROCEDURE DIVISION USING LNK-PARAM-BLOCK.

 CONTROLLING SECTION.

*---------------------------------------------------------------*
*  associate the user data area with the pointer in
*  lnk-parm-block.
*---------------------------------------------------------------*

     SET ADDRESS OF INPUT-AREA TO LNK-DBLOCK-PTR.

        EVALUATE TRUE

           WHEN START-CONNECTION
              PERFORM PROGRAM-INITIALIZE

           WHEN OTHER
              PERFORM PROGRAM-BODY

        END-EVALUATE.
        EXIT PROGRAM.

 PROGRAM-INITIALIZE SECTION.

*--- This code would include the initialization code
*--- for your server program eg. opening your application
*--- data files.

     ......

 PROGRAM-BODY SECTION.

*--- This section would include your application
*--- processing code eg. read and writing of data
*--- files.

     ......

If you choose to handle error message displays yourself, you will need to add code similar to the following to your program's initial EVALUATE statement:

           WHEN COMMS-ERROR
              PERFORM SHOW-ERROR

           ......

 SHOW-ERROR SECTION.
     DISPLAY LNK-ERROR-LOC AT 2201
     DISPLAY LNK-ERROR-MSG AT 2301 WITH SIZE LNK-ERROR-MSG-LEN.
     EXIT.

2.8 Running a Client/Server Binding Application

The mfserver module is provided in .int code format so that it can be run as it is or generated into .gnt code.

If you have a UNIX system running Micro Focus COBOL 3.2 or later, you can move the .int module to your UNIX system and link it with other programs to create an executable module.

The mfclient and mfserver modules are run as standard COBOL programs, with both the client and server components started manually.

To run the client/server binding:

  1. If you are using the CCI communications API, first start the server program. If you are using AAI, this step is unnecessary as AAI will start the program automatically when the client requests the service.

  2. Start the client program.

The command line to start the server program on UNIX is:

cobrun mfserver [-b] [-p protocol] [-s server-name] [-v]

and on Windows:

run mfserver [-b] [-p protocol] [-s server-name] [-v]

where:

-b Allows you to run the server as a background process. On UNIX systems, the command line should be terminated with the '&' character. Any error messages produced by the server will be stored in the log file (mfclisrv.log).
-p protocol Specifies the communications protocol.
-s server-name Indicates a server-name other than the default (mfclisrv).
-v Displays the mfserver version number.

The command line to start the client program is:

run program-name [config-filename]

where:

program-name Specifies the name of the user interface program.
config-filename Specifies the name of the configuration file to be used.

2.9 Animating Your Application

You can animate your client program using the standard animation facilities of NetExpress.

You can animate your server program by setting a configuration file parameter, srvanim=y (see Configuration File Parameters).

On PC servers, the Animator is started automatically when a client connects to the server if srvanim=y is set.

On UNIX servers, the Animator is run on the terminal from which mfserver was started and so requires mfserver to be running in foreground mode. This can cause problems as it is preferable to run mfserver as a background process. A further restriction is that only one user can animate through mfserver at any one time. These problems can be avoided by setting srvanim=x,filename where filename is a file created using the touch command. On the terminal that you want to use to display Animator output, set COBANIM_2=animator and then run the command anim filename. On the terminal that you want to use for your standard input and output, run your application in the normal way, having added srvanim=x,filename to your configuration file.

2.10 Managing the Server

If you are using the CCI communications API, the behaviour of the server can be altered by running the program mfcsmgr and passing it the required parameters and values. These parameters can be divided into two groups: location and action. The parameters in the location group allow you to locate the target server, and can have settings m, p, and s. The action parameters control how the target server will be affected and can have settings a, c, o, r and t. Certain action parameters cannot be specified in combination with any other, these are o, r and t.

If you are using the AAI communications API, the behaviour of the server is controlled via the AAI administration system. The mfcsmgr program has no effect on applications running under AAI control.

2.10.1 Shutting Down mfserver

The spawned servers are terminated by the client program when the client makes a normal exit. If you are using the CCI communications API, the initial server program does not terminate when its clients terminate, so if you want to shut down this server you must do so manually. If you are using the AAI communications API, the initial server program is terminated automatically following termination of the client.

2.10.2 Managing Authorisation Passwords

To prevent accidental shutdown of an active server when you are using the CCI communications API, it is possible to assign a password to each server. This password must be supplied before the server can be stopped or its parameters changed.

2.10.3 Setting The Maximum Number Of Clients

The default number of clients the server can support using the CCI communications API is 25, but you can set a lower limit using one of the mfcsmgr functions. The number you select is stored in the password file and will be used each time the server is started.

2.10.4 Enabling Server Override

The server can support override options for the server-name, protocol, and machine-name. As the server does not use a configuration file the override parameters are supplied using the mfcsmgr program. This generates a short exchange between the client and the server which processes the selected function. This override capability is provided for the CCI communications API only. Applications using the AAI communications API use the AAI administration system to control server options.

The command line syntax for mfcsmgr is:

Windows:

run mfcsmgr [-a] [-c nnnnn] [-d] [-i filename][- m machine-name]
            [-p protocol] [-s server-name] [-o m, machine-name]
            [-o p, protocol] [-o r] [-o s, server-name] [-t] [-v]

UNIX:

cobrun mfcsmgr [-a] [-c nnnnn] [-d] [-i filename] [- m machine-name]
               [-p protocol] [-s server-name] [-o m, machine-name]
               [-o p, protocol] [-o r] [-o s, server-name] [-t] [-v]

where:

-a Changes the authorisation password associated with the target server.
-c,nnnnn Sets the number of clients the server can support.
-d Deletes the local overide file (mfcsovrd.cfg) when the client exits.
-i filename Installs the specified file in the client's local directory when the client exits.
-m machine-name Specifies the name of the machine on which the target server is running. This is required if the same server-name is used on more than one platform.
-p protocol Specifies the communications protocol being used: TCP/IP (CCITC32), NetBEUI (CCINB32), Novell IPX (CCIIX32) or Dynamic Data Exchange (CCIDE32).
-s server-name Indicates a server-name other than the default (mfclisrv).
-o m,machine-name Specifies the machine-name on which the overriding is running.
-o p,protocol Uses this protocol to access the overriding server.
-o r Resets active override. Reverts to original settings.
-o s,server-name Overrides connections to the target server by directing them to this server.
-t Terminates the server
-v Displays the mfclient version number.

All the above flags can be specified with a - or /, and are not case-sensitive.

2.11 Advanced Topics

2.11.1 System Log File

Both mfclient and mfserver maintain a log of errors and messages. All entries are date- and time-stamped and are kept in a file called mfclisrv.log which is stored in the directory in which the programs were started or in the directory named in the MFLOGDIR environment variable. Check this log from time to time to ensure that your system is performing correctly.

2.11.2 Creating Audit Trails

You can create an audit trail of dates and times that clients connected to servers. To enable this feature, simply set useraudit=y in your configuration file.

This information is created in the system log file described above.

2.11.3 Overriding Configuration File Entries

During the start-up process for each client, once the configuration file has been read, the client/server binding searches for a file called mfcsovrd.cfg. It searches for this file in the system log file directory. If the file is found, its contents are used to override any parameters previously set up using the configuration file. The format of the override file is identical to that of the standard configuration file with the exception of a single additional entry, override-cntrl. This entry is used to indicate the subject of the override which may be a server-name or a tag-name. If a server-name is specified, any clients using that server have their parameters modified by the contents of the override file. If a tag-name is specified, only those clients using the specified tag-name have their parameters altered.

The client override facility can be used, for example, if a server is unavailable and applications need to be run on another machine. You could of course change the individual configuration files, but a single override file can be used to re-route any number of applications.

The override facility can also be used on the server, but in this case the server machine needs to be up and running. As before, either server-names or tag-names can be overridden.

An entry is added to the log file whenever an override file is detected, and all parameters which are subject to the override process are logged.

The following example shows how the override facility can be used to re-route clients to another server:

[override-cntrl]
override=servername
[oldserver]
servername=newserver

In this example the [override-cntrl] section specifies that the subject of the override is a server-name (override=servername) and then, under the the old server-name ([oldserver]), the new server-name (servername=newserver) is specified. This would result in the following log file entries:

20/04/1998 11:01:02 Using Local File: mfcsovrd.cfg
Overriding Entries for Servername:OLDSERVER
servername=newserver
20/04/1998 11:01:02 Override Completed:

The following example shows how the override facility can be used to override the server being used by all those clients which are using a specified tag:

[override-cntrl]
override=tagname
[mf-clisrv]
servername=newserv

In this example the [override-cntrl] section specifies that the subject of the override is a tag-name (override=tagname) and then, under the tag-name ([mf-clisrv]), the parameter to be overridden (in this case the server-name) is specified (servername=newserv). This would result in the following log file entries:

20/04/1998 11:04:02 Using Local File: mfcsovrd.cfg
Overriding Entries for Tagname:MF-CLISRV
servername=newserv
20/04/1998 11:04:02 Override Completed:

2.11.4 Using Dialog System 'Callout'

If you wish to use the callout facility of Dialog System with the Client/Server Binding, you have to make a small change to your user client program, and create programs to service the callout request at either end of the connection. You need to add two lines and a directive to your user client program, as follows-:

At the start of the program:

$set ans85 linkcount(128)

In WORKING-STORAGE:

 01  lnk-param-block-addr         POINTER EXTERNAL.

In the PROCEDURE DIVISION:

SET lnk-param-block-addr TO ADDRESS OF lnk-param-block

The reason for this is so that the program called by dialog to handle the callout request has access to the same parameter entries as your user client program. This is achieved by use of an external data pointer. The callout program needs to have code similar to that in the example below-:

      $set ans85
       WORKING-STORAGE SECTION.

       01  lnk-param-block-addr         POINTER EXTERNAL.

       LINKAGE SECTION.

       COPY "mfclisrv.cpy".

       01  user-data-block              PIC X(30).

       PROCEDURE DIVISION.
       Controlling SECTION.
           SET ADDRESS OF lnk-param-block TO lnk-param-block-addr
           SET ADDRESS OF user-data-block TO lnk-ublock-ptr
           SET ds-callout TO TRUE
           MOVE "callosrv" TO user-data-block
           CALL lnk-client USING lnk-param-block
           EXIT PROGRAM.

The name of the program which will receive the callout request on the server is setup in the user-data-block. If the name of this program can only be determined from data in any of the control blocks used by Dialog System, you will have to make these accessible using coding similar to that in the following program-:

      $set ans85 linkcount(128)
       WORKING-STORAGE SECTION.

       01  lnk-param-block-addr         POINTER EXTERNAL.

       LINKAGE SECTION.

       COPY "mfclisrv.cpy".

       01  user-data-block              PIC X(30).

           COPY "DS-CNTRL.MF".
           COPY "CUSTOMER.CPB".

       PROCEDURE DIVISION USING ds-control-block customer-data-block.
       Controlling SECTION.
           SET ADDRESS OF lnk-param-block TO lnk-param-block-addr
           SET ADDRESS OF user-data-block TO lnk-ublock-ptr
           SET ds-callout TO TRUE
           EVALUATE cust-callout-flg
              WHEN 1
                 MOVE "callprog1" TO user-data-block
              WHEN 2
                 MOVE "callprog2" TO user-data-block
           END-EVALUATE
           CALL lnk-client USING lnk-param-block
           EXIT PROGRAM.

The callout program on the server side will look something like this-:

      $set ans85

       LINKAGE SECTION.

           COPY "DS-CNTRL.MF".
           COPY "CUSTOMER.CPB".

       PROCEDURE DIVISION USING ds-control-block customer-data-block.
       Controlling SECTION.
           ............ Code to
               ........... process callout
                  ............ request....
           EXIT PROGRAM.

2.11.5 Using Existing Non-Dialog System programs as the server module

The Client/Server Binding has the ability to use an existing Dialog System program as the user server module. It does this when srvtier=<your program> (for details, see Configuration File Parameters).

In this instance, mfserver expects to be called with a set of parameters which conform to the Dialog System API. When used in this way, the user program makes calls to mfserver to transfer data to the client and so becomes the controlling element on the server. It is possible to have other programs perform the same function, as long as they conform to the API used by Dialog System.

The Client/Server Binding normally checks certain items within the first parameter of the API, and performs particular functions based on the value found. This behaviour can be prevented by setting these items to HIGH-VALUES. You need to call mfserver with two parameters:

The size of both these items needs to be defined in the configuration file used to run the application. A pair of demo programs and the necessary configuration file have been provided here as an example, they are:

   o nodscli.cbl - The client module
   
      $set ans85
       WORKING-STORAGE SECTION.
       01  w-prog-id                pic x(30) value
           '"@(#) nodscli.cbl 1.1.1"'.

       copy "mfclisrv.cpy".

       01  ws-scrn-pos.
           03  ws-line              pic 99 value 07.
           03  ws-col               pic 99 value 1.

       LINKAGE SECTION.
       01  ds-control-block         pic x(6).

       01  NODS-DATA-BLOCK.
           03  NODS-PARAM           PIC 99.
           03  NODS-DATA            PIC X(120).

       procedure division.
       000-control section.
      * Make initial contact with the server
          call lnk-client using lnk-param-block
          if start-connection
             set address of ds-control-block to lnk-cblock-ptr
             set address of nods-data-block to lnk-dblock-ptr
          end-if

          display spaces at 0101 
                "Starting Test Session" at 0510
          perform 010-run-test until nods-param = 10
      * Send disconnect request
          set client-ending to true
          call lnk-client using lnk-param-block
          display "Test Session Completed" at 2010
          stop run.

       010-run-test section.
      * Get data from server 
          call lnk-client using lnk-param-block
          add 1 to ws-line
          display nods-data(1:80) at ws-scrn-pos
          exit.

   o nodssrv.cbl - The server module

      $set ans85
       working-storage section.
       01  w-prog-id                 pic x(30) value
           '"@(#) nodssrv.cbl 1.1.1"'.

       01  dummy-cntrl-block         pic x(6) value high-values.

       01  NODS-DATA-BLOCK.
           03  NODS-PARAM            PIC 99.
           03  NODS-DATA             PIC X(120).

           copy "mfclisrv.cpy".

       01  ws-sub                    pic 99.
       01  ws-table.
          03  ws-letts               pic x occurs 10.

       procedure division.
       controlling section.

          move "ABCDEFGHIJ" to ws-table
          move 0 to nods-param
      *
      * Establish contact with the client.
      * This needs to be done as early as possible to stop the 
      * Client timing out and 'polling' the network looking for
      * the server.
      *
          call "mfserver" using dummy-cntrl-block nods-data-block
      *
      * You must ensure that you don't call 'mfserver' after the
      * client has issued a shutdown request. In this system 
      * nods-param = 10 causes to client to issue the shutdown
      * request and ends the driving loop in this program.
      *
          perform varying nods-param from 1 by 1
             until nods-param > 10
                perform varying ws-sub from 1 by 1
                  until ws-sub > 80
                     move ws-letts(nods-param)
                       to nods-data(ws-sub:1)
                end-perform
                call "mfserver" using dummy-cntrl-block
                                      nods-data-block
          end-perform
          stop run.


   o nods.cfg    - The configuration file

********************************************************************************
* Micro Focus - Client Server Module Configuration File                        *
********************************************************************************

[mf-clisrv]
srvtier=nodssrv
cblksize=6
dblksize=122
servername=nods

When compiled and run, the server program passes data to the client without losing its position which would occur if it was a called program and had to use an 'EXIT PROGRAM' each time data needed to be passed to the client. If your existing program is unable to conform to the required Dialog System API, you can still use the above method by introducing a small bridge program as decribed below.

       WORKING-STORAGE SECTION.

       01  dummy-control-block          PIC X(6) VALUE HIGH-VALUES.
       01  grouped-data-block.
          03  ws-param-1                PIC X(50).
          03  ws-param-2                PIC X(120).
          03  ws-param-3                PIC X(18).
          03  ws-param-4                PIC X(48).

       LINKAGE SECTION.

       01  lnk-param-1                  PIC X(50).
       01  lnk-param-2                  PIC X(120).
       01  lnk-param-3                  PIC X(18).
       01  lnk-param-4                  PIC X(48).

       PROCEDURE DIVISION USING
               lnk-param-1 lnk-param-2
               lnk-param-3 lnk-param-4.

           MOVE lnk-param-1 TO ws-param-1
           MOVE lnk-param-2 TO ws-param-2
           MOVE lnk-param-3 TO ws-param-3
           MOVE lnk-param-4 TO ws-param-4

           CALL "mfserver" USING dummy-control-block
                                 grouped-data-block

           MOVE ws-param-1 TO lnk-param-1
           MOVE ws-param-2 TO lnk-param-2
           MOVE ws-param-3 TO lnk-param-3
           MOVE ws-param-4 TO lnk-param-4

           EXIT PROGRAM.

2.11.6 Using The In-line Configuration Facility

One of the most powerful features of the client/server binding is the ability to control the communications requirements from configuration files. This does mean, however, that end-users can affect the way an application runs by changing entries in these files, and this may not be desirable.

It is possible, therefore, to provide all the configuration parameters within the client program. This means that the end-user cannot alter the way an application behaves because it no longer uses a configuration file. There is still no need to write complex communications code, you simply supply the required parameters within your client program. The process is started by setting load-inline-cfg and completed by setting end-inline-cfg. Each parameter entry is loaded into the lnk-error-msg field and mfclient is called to process it. The parameters have to be supplied before the main processing loop is entered. An example is given below.

       WORKING-STORAGE SECTION.

       COPY "mfclisrv.cpy".

       LINKAGE SECTION.

       01 INPUT-REC                 PIC X(32767)

       PROCEDURE DIVISION.

       Client-Control SECTION.

          SET load-inline-cfg TO TRUE
          MOVE "clierrprog=same" TO lnk-error-msg
          CALL lnk-client USING lnk-param-block

          MOVE "srverrprog=same" TO lnk-error-msg
          CALL lnk-client USING lnk-param-block

          MOVE "servername=mainserv" TO lnk-error-msg
          CALL lnk-client USING lnk-param-block

          SET end-inline-cfg TO TRUE

      *  The main loop is repeated until the connection with
      *  the server ends

          PERFORM UNTIL End-Connection

      *  'lnk-client' holds the name 'mfclient'
      *  The first time through we initialize the system and establish
      *  contact with the server.

             CALL lnk-client USING lnk-param-block

             EVALUATE TRUE

                WHEN start-connection

           ........ The rest of the program is standard from this
           ........... point onwards  ............

It is also possible to combine an external configuration file with the in-line configuration facility. This provides the best of both worlds in that the end-user can modify the system to their own requirements, but ultimate control remains within the client program. The configuration file is processed first followed by the in-line entries. This means that any unwanted parameters supplied in the configuration file can be overwritten by the in-line entry. In this case the process is started by setting use-combined-cfg and completed as before by setting end-inline-cfg.

       WORKING-STORAGE SECTION.

       COPY "mfclisrv.cpy".

       LINKAGE SECTION.

       01 INPUT-REC                 PIC X(32767)

       PROCEDURE DIVISION.

       Client-Control SECTION.

          SET use-combined-cfg TO TRUE
          CALL lnk-client USING lnk-param-block

          SET load-inline-cfg TO TRUE
          MOVE "servername=mainserv" TO lnk-error-msg
          CALL lnk-client USING lnk-param-block

          SET end-inline-cfg TO TRUE

      *  The main loop is repeated until the connection with
      *  the server ends

          PERFORM UNTIL End-Connection

      *  'lnk-client' holds the name 'mfclient'
      *  The first time through we initialize the system and establish
      *  contact with the server.

             CALL lnk-client USING lnk-param-block

             EVALUATE TRUE
                WHEN start-connection

           ........ The rest of the program is standard from this
           ........... point onwards  ............

2.11.7 The Reduced Data Transfer Facility

The client/server binding assigns a buffer large enough to hold the data blocks defined in the configuration file. This buffer is transferred back and forth whenever control is shifted between the client and server programs. This can impose a load on the network which some users may find unacceptable. Imagine you have a buffer of 24K which contains a 22K record area. If the file which holds these records has a 10-byte key, sending the key from client to server uses 24K when only 10 bytes are actually required. In reality, you do need one or two bytes more than the size of the data, but much less than the size of the entire buffer. This is what Reduced Data Transfer (RDT) provides, a way for you to control the amount of data being passed across the network and for you to limit this data to the absolute minimum required. This facility is only available if you are using the CCI communications API. It is not required if you are using the AAI communications API because the AAI API includes the facility to compress data automatically. Using the RDT facility with the AAI communications API may cause unpredictable results.

Reduced Data Transfer requires a contol flag (use-rdt) and three parameters:

lnk-usr-fcode The user function indicator. This indicates to the receiver what to do with the data that has just arrived.
lnk-usr-retcode The buffer start point. This indicates which of the four data areas will be used as the start point for the transfer. Valid values are: 1=cblock, 2=dblock, 3=eblk, and 4=ublk. The numbers 11 through 14 can also be used to indicate the same address areas but using data compression. Data compression must have been enabled via a configuration file entry or the base (un-compressed) option will be used. A value of zero results in nothing being transferred. This allows you to have a NULL operation without changing the flow of your code by adding various IF statements. This is useful if you choose to process certain functions locally in order to further reduce network traffic.
lnk-data-length The length of data to be transferred.

Consider an application which allows you to add, delete, and load customer details to/from an index file. The record key for the customer details file is a customer code. The application also has an option to clear all customer information from the interface. The code extract below is based on this example application and uses the user-data-block area to hold the record key which is six bytes long. The data block area (dblksize) used by the application to pass the customer record details between the client and the server is called customer-data-block. The data item customer-c-code is a 6-byte data item within customer-data-block and is used to store the record key.

On the client, the code would be similar to:

             EVALUATE TRUE

                WHEN customer-load-flg-true

*---        User has entered customer code and selected the "LOAD"
*---        option on the interface to read and display the customer
*---        details relating to that code.

                   MOVE customer-c-code TO user-data-block
                   SET use-rdt TO TRUE
                   MOVE 1 TO lnk-usr-fcode
                   MOVE 4 TO lnk-usr-retcode
                   MOVE 6 TO lnk-data-length

                WHEN customer-del-flg-true

*---        User has entered a customer code selected the DELETE
*---        option to delete the customer record from the file.

                   MOVE customer-c-code TO user-data-block
                   SET use-rdt TO TRUE
                   MOVE 2 TO lnk-usr-fcode
                   MOVE 4 TO lnk-usr-retcode
                   MOVE 6 TO lnk-data-length
                   initialize customer-data-block

                WHEN customer-clr-flg-true

*---        User has selected the CLEAR option to clear the current
*---        customer details from the screen.

                   SET use-rdt TO TRUE
                   MOVE 0 TO lnk-usr-retcode
                   initialize customer-data-block
                   PERFORM Set-Up-For-Refresh-Screen
             END-EVALUATE

The clear option uses a NULL operation because clearing the record is done locally so there is no need to contact the server. Below is an extract from the server program showing the code required to process Reduced Data Transfer. The client/server binding sets the flag send-via-rdt so that you can check the values of lnk-usr-fcode. On the server, the code would be similar to:

             WHEN send-via-rdt
                EVALUATE lnk-usr-fcode
                   WHEN 1

*--- For the LOAD function the server program reads the customer
*--- details from the data file and sends the data back to the
*--- client using the data area customer-data-block rather using
*--- the RDT faclity.  Unless the RDT flag is set the client/server
*--- bindings will always pass the complete data area (defined by
*--- dblksize in the configuration file) between the client and the
*--- server.
                      MOVE user-data-block TO customer-c-code
                      SET customer-load-flg-true TO TRUE
                      PERFORM ....... rest of program.......
                   WHEN 2
                      MOVE user-data-block TO customer-c-code
                      SET customer-del-flg-true TO TRUE
                      PERFORM ....... rest of program.......
                END-EVALUATE

The Csbind demonstration application uses the Reduced Data Transfer facility.

2.11.8 Server Controlled File Management Facility

One of the problems that accompanies any client/server solution, especially as the number of clients increases, is the management of client program updates and other changes.

The override facility (see Overriding Configuration File Entries) enables you to re-route client applications while server maintenance is carried out without having to change each client's configuration file entries. The override can be either local or remote but installing and removing a local override file on each client can be time-consuming.

The mfcsmgr program enables you to install and delete override files on the client using the -i and -d options respectively (see Managing the Server). The installation/deletion is carried out as the client program exits.

In fact, the -i option of the mfcsmgr program enables you to install any type of file on the client system (in the client's local directory). This means that you can use it to install new screensets or program files, enabling updates to be distributed from a central point. For security reasons, the delete option has not been similarly enhanced, it will only delete an override file, that is, a file called mfcsovrd.cfg.

Files to be installed using the -i option must be located on the server. If the file is in the directory that mfserver was started from, you need only specify the filename. If it is anywere else, you must supply a full pathname in such a way that the filename can be extracted from the path, for example, /u/live/update/newprog.int, d:\testprog.int and $LIVE/newtest.int are all valid but $newfile is not.

No programming changes are required to use these functions, a message is displayed informing the client that a file is being transferred and the details are recorded in the system log file.

2.12 Client/Server Binding Limitations

The client/server binding imposes very few limitations, but you should be aware of the following issues.


Copyright © 1998 Micro Focus Limited. All rights reserved.
This document and the proprietary marks and names used herein are protected by international law.
Previous Introduction