  
  [1X6 Client's functionality[0X
  
  Sending  and  getting  requests  to the [5XSCSCP[0m server(s), the client operates
  with   processes.   Process   is   an   abstraction  which  encapsulates  an
  [10XInputOutputTCPStream[0m  (see  [2XIsInputOutputTCPStream[0m ([14X3.1-1[0m)) from a client to
  the  server  and the process ID of the CAS running as a server (deduced from
  the  connection initiation message; may be unassigned, if the server CAS did
  not communicate it).
  
  
  [1X6.1 Sending request and getting result[0X
  
  [1X6.1-1 IsProcess[0m
  
  [2X> IsProcess___________________________________________________________[0Xfilter
  
  This  is  the  category of processes. Processes in this category are created
  using the function [2XNewProcess[0m ([14X6.1-2[0m).
  
  [1X6.1-2 NewProcess[0m
  
  [2X> NewProcess( [0X[3Xcommand, listargs, server, port[0X[2X ) ____________________[0Xfunction
  [6XReturns:[0X  object in the category [10XIsProcess[0m
  
  [3Xcommand[0m  and  [10Xserver[0m are strings, [3Xlistargs[0m is a list of [5XGAP[0m objects and [10Xport[0m
  is  an integer. Calls the [5XSCSCP[0m procedure with the name [3Xcommand[0m and the list
  of  arguments  [3Xlistargs[0m  at  the  server  and port given by [10Xserver[0m and [10Xport[0m.
  Returns  an  object in the category [10XIsProcess[0m for the subsequent waiting the
  result from its underlying stream.
  
  It accepts the following options:
  
  --    [10Xoutput:="object"[0m  is  used  to specify that the server must return the
        actual object evaluated as a result of the procedure call. This is the
        default  action  requested  by  the  client  if  the  [10Xoutput[0m option is
        omitted.
  
  --    [10Xoutput:="cookie"[0m  is  used to specify that the result of the procedure
        call  should  be  stored on the server, and the server should return a
        remote object (see [14X6.2[0m ) pointing to that result (that is, a cookie);
  
  --    [10Xoutput:="nothing"[0m  is  used  to specify that the server is supposed to
        reply  with  a  [10Xprocedure_completed[0m message carrying no object just to
        signal   that   the   call   was   completed   successfully  (for  the
        compatibility,  this  will  be  evaluated  to  a [10X"procedure completed"[0m
        string on the client's side);
  
  --    [10Xcd:="cdname"[0m is used to specify that the [5XOpenMath[0m symbol corresponding
        to  the  first  argument [3Xcommand[0m should be looked up in the particular
        content  dictionary  [10Xcdname[0m.  Otherwise,  it will be looked for in the
        default  content  dictionary  ([10Xscscp_transient_1[0m  for  the  [5XGAP[0m  [5XSCSCP[0m
        server);
  
  --    [10Xdebuglevel:=N[0m  is  used  to  obtain  additional information attributes
        together  with the result. The [5XGAP[0m [5XSCSCP[0m server does the following: if
        [10XN=1[0m,  it  will  report  about the CPU time in milliseconds required to
        compute  the  result;  if  [10XN=2[0m  it  will additionally report about the
        amount  of  memory  used  by  [5XGAP[0m in bytes will be returned (using the
        output of [2XMemoryUsageByGAPinKbytes[0m ([14X9.2-8[0m) converted to bytes); if [10XN=3[0m
        it  will additionally report the amount of memory in bytes used by the
        resulting  object  and its subobjects (using the output of [2XMemoryUsage[0m
        ([14XReference: MemoryUsage[0m)).
  
  See [2XCompleteProcess[0m ([14X6.1-3[0m) and [2XEvaluateBySCSCP[0m ([14X6.1-4[0m) for examples.
  
  [1X6.1-3 CompleteProcess[0m
  
  [2X> CompleteProcess( [0X[3Xprocess[0X[2X ) _______________________________________[0Xfunction
  [6XReturns:[0X  record with components [10Xobject[0m and [10Xattributes[0m
  
  The function waits, if necessary, until the underlying stream of the process
  will contain some data, then reads the appropriate [5XOpenMath[0m object from this
  stream and closes it.
  
  It has the option [10Xoutput[0m which may have two values:
  
  --    [10Xoutput:="cookie"[0m has the same meaning as for the [2XNewProcess[0m ([14X6.1-2[0m)
  
  --    [10Xoutput:="tree"[0m  is  used  to specify that the result obtained from the
        server   should  be  returned  as  an  XML  parsed  tree  without  its
        evaluation.
  
  In  the  following  example  we  demonstrate combination of the two previous
  functions   to   send   request   and  get  result,  calling  the  procedure
  [10XWS_Factorial[0m, installed in the previous chapter:
  
  [4X---------------------------  Example  ----------------------------[0X
    [4X[0X
    [4Xgap> s := NewProcess( "WS_Factorial", [10], "localhost", 26133 );                  [0X
    [4X#I  Creating a socket ...[0X
    [4X#I  Connecting to a remote socket via TCP/IP ...[0X
    [4X#I  Got connection initiation message [0X
    [4X#I  Request sent ...[0X
    [4X< process at localhost:26133 pid=6543 >[0X
    [4Xgap> x := CompleteProcess(s);[0X
    [4Xrec( object := "3628800", attributes := [ [ "call_id", "localhost:26133:6543" ] ] )[0X
    [4X[0X
  [4X------------------------------------------------------------------[0X
  
  See  more  examples  in  the  description  of  the  function [2XEvaluateBySCSCP[0m
  ([14X6.1-4[0m),  which  combines  the two previous functions by sending request and
  getting result in one call.
  
  [1X6.1-4 EvaluateBySCSCP[0m
  
  [2X> EvaluateBySCSCP( [0X[3Xcommand, listargs, server, port[0X[2X ) _______________[0Xfunction
  [6XReturns:[0X  record with components [10Xobject[0m and [10Xattributes[0m
  
  [3Xcommand[0m  and  [10Xserver[0m are strings, [3Xlistargs[0m is a list of [5XGAP[0m objects and [10Xport[0m
  is  an integer. Calls the SCSCP procedure with the name [3Xcommand[0m and the list
  of arguments [3Xlistargs[0m at the server and port given by [10Xserver[0m and [10Xport[0m.
  
  Since   [2XEvaluateBySCSCP[0m  combines  [2XNewProcess[0m  ([14X6.1-2[0m)  and  [2XCompleteProcess[0m
  ([14X6.1-3[0m),  it  accepts  all  options  which  may  be used by that functions (
  [10Xoutput[0m, [10Xcd[0m and [10Xdebuglevel[0m ) with the same meanings.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4X[0X
    [4Xgap> EvaluateBySCSCP( "WS_Factorial",[10],"localhost",26133);[0X
    [4X#I  Creating a socket ...[0X
    [4X#I  Connecting to a remote socket via TCP/IP ...[0X
    [4X#I  Got connection initiation message[0X
    [4X#I  Requesting version 1.3 from the server ...[0X
    [4X#I  Server confirmed version 1.3 to the client ...[0X
    [4X#I  Request sent ...[0X
    [4X#I  Waiting for reply ...[0X
    [4Xrec( attributes := [ [ "call_id", "localhost:26133:2442:6hMEN40d" ] ], [0X
    [4X     object := 3628800 )[0X
    [4Xgap> SetInfoLevel(InfoSCSCP,0);[0X
    [4Xgap> EvaluateBySCSCP( "WS_Factorial",[10],"localhost",26133 : output:="cookie" ); [0X
    [4Xrec( attributes := [ [ "call_id", "localhost:26133:2442:jNQG6rml" ] ], [0X
    [4X  object := < remote object TEMPVarSCSCP@localhost:26133 > )[0X
    [4Xgap> EvaluateBySCSCP( "WS_Factorial",[10],"localhost",26133 : output:="nothing" );[0X
    [4Xrec( attributes := [ [ "call_id", "localhost:26133:2442:9QHQrCjv" ] ], [0X
    [4X  object := "procedure completed" )[0X
    [4X[0X
  [4X------------------------------------------------------------------[0X
  
  Now  we  demonstrate the procedure [10XGroupIdentificationService[0m, also given in
  the previous chapter:
  
  [4X---------------------------  Example  ----------------------------[0X
    [4X[0X
    [4Xgap> G:=SymmetricGroup(4);[0X
    [4XSym( [ 1 .. 4 ] )[0X
    [4Xgap> gens:=GeneratorsOfGroup(G);[0X
    [4X[ (1,2,3,4), (1,2) ][0X
    [4Xgap> EvaluateBySCSCP( "GroupIdentificationService", [ gens ],[0X
    [4X>                     "localhost", 26133 : debuglevel:=3 ); [0X
    [4X#I  Creating a socket ...[0X
    [4X#I  Connecting to a remote socket via TCP/IP ...[0X
    [4X#I  Got connection initiation message[0X
    [4X#I  Requesting version 1.3 from the server ...[0X
    [4X#I  Server confirmed version 1.3 to the client ...[0X
    [4X#I  Request sent ...[0X
    [4X#I  Waiting for reply ...[0X
    [4Xrec( attributes := [ [ "call_id", "localhost:26133:2442:xOilXtnw" ], [0X
    [4X      [ "info_runtime", 6 ], [ "info_memory", 670175232 ], [0X
    [4X      [ "info_message", "Memory usage for the result is 24 bytes" ] ], [0X
    [4X  object := [ 24, 12 ] )[0X
    [4X[0X
  [4X------------------------------------------------------------------[0X
  
  Service provider may suggest to the client to use a counterpart function
  
  [4X---------------------------  Example  ----------------------------[0X
    [4X[0X
    [4XIdGroupWS:=function( G )[0X
    [4Xlocal H, result;[0X
    [4Xif not IsPermGroup(G) then[0X
    [4X  H:= Image( IsomorphismPermGroup( G ) );[0X
    [4Xelse[0X
    [4X  H := G;[0X
    [4Xfi;  [0X
    [4Xresult := EvaluateBySCSCP ( "GroupIdentificationService", [0X
    [4X            [ GeneratorsOfGroup(H) ], "localhost", 26133 );[0X
    [4Xreturn result.object;[0X
    [4Xend;[0X
    [4X[0X
  [4X------------------------------------------------------------------[0X
  
  which works exactly like [2XIdGroup[0m ([14XReference: IdGroup[0m):
  
  [4X---------------------------  Example  ----------------------------[0X
    [4X[0X
    [4Xgap> G:=DihedralGroup(64);[0X
    [4X<pc group of size 64 with 6 generators>[0X
    [4Xgap> IdGroupWS(G);[0X
    [4X#I  Creating a socket ...[0X
    [4X#I  Connecting to a remote socket via TCP/IP ...[0X
    [4X#I  Got connection initiation message [0X
    [4X#I  Request sent ...[0X
    [4X#I  Waiting for reply ...[0X
    [4X[ 64, 52 ][0X
    [4X[0X
  [4X------------------------------------------------------------------[0X
  
  [1X6.1-5 TerminateProcess[0m
  
  [2X> TerminateProcess( [0X[3Xprocess[0X[2X ) ______________________________________[0Xfunction
  
  The  function  is  supposed to send an "out-of-band" interrupt signal to the
  server.  Current  implementation  works  only  when the server is running as
  "localhost" by sending a [10XSIGINT[0m to the server using its PID contained in the
  [3Xprocess[0m.  It will do nothing if the server is running remotely, as the [5XSCSCP[0m
  specification  allows  the  server  to  ignore  interrupt  messages.  Remote
  interrupts will be introduced in one of the next versions of the package.
  
  
  [1X6.2 Remote objects[0X
  
  The  [5XSCSCP[0m  package  introduces  new  kind of objects - [13Xremote objects[0m. They
  provide an opportunity to manipulate with objects on remote services without
  their  actual  transmitting  over  the  network.  Remote  objects  store the
  information  that  allows to access the original object: the server name and
  the  port  number through which the object can be accessed, and the variable
  name  under  which it is stored in the remote system. Two remote objects are
  equal if and only if all these three parameters coincide.
  
  There are two types of remote object which differ by their lifetime:
  
  --    temporary remote objects which exist only within a single session;
  
  --    persistent remote objects which stay alive across multiple sessions.
  
  First  we  show the example of the temporary remote object in a session. The
  procedure  [10XPointImages[0m  returns  the  set  of  images of a point i under the
  generators  of  the  group G. First we create the symmetric group S_3 on the
  client  and store it remotely on the server (call 1), then we compute set of
  images  for  i=1,2  (calls 2,3) and finally demonstrate that we may retrieve
  the group from the server (call 4):
  
  [4X---------------------------  Example  ----------------------------[0X
    [4X[0X
    [4Xgap> stream:=InputOutputTCPStream( "localhost", 26133 );[0X
    [4X#I  Creating a socket ...[0X
    [4X#I  Connecting to a remote socket via TCP/IP ...[0X
    [4X< input/output TCP stream to localhost:26133 >[0X
    [4Xgap> StartSCSCPsession(stream);[0X
    [4X#I  Got connection initiation message[0X
    [4X#I  Requesting version 1.3 from the server ...[0X
    [4X#I  Server confirmed version 1.3 to the client ...[0X
    [4X"localhost:26133:6184"[0X
    [4Xgap> OMPutProcedureCall( stream, "store_session", [0X
    [4X>       rec( object := [ SymmetricGroup(3) ], [0X
    [4X>        attributes := [ [ "call_id", "1" ], [0X
    [4X>                        ["option_return_cookie"] ] ) );[0X
    [4Xtrue[0X
    [4Xgap> SCSCPwait( stream );[0X
    [4Xgap> G:=OMGetObjectWithAttributes( stream ).object;[0X
    [4X< remote object TEMPVarSCSCPoS5nhta3@localhost:26133 >[0X
    [4Xgap> OMPutProcedureCall( stream, "PointImages", [0X
    [4X>       rec( object := [ G, 1 ], [0X
    [4X>        attributes := [ [ "call_id", "2" ] ] ) );[0X
    [4Xtrue[0X
    [4Xgap> SCSCPwait( stream );[0X
    [4Xgap> OMGetObjectWithAttributes( stream );[0X
    [4Xrec( attributes := [ [ "call_id", "2" ] ], object := [ 2 ] )[0X
    [4Xgap> OMPutProcedureCall( stream, "PointImages", [0X
    [4X>       rec( object := [ G, 2 ], [0X
    [4X>        attributes := [ [ "call_id", "3" ] ] ) );[0X
    [4Xtrue[0X
    [4Xgap> SCSCPwait( stream );[0X
    [4Xgap> OMGetObjectWithAttributes( stream );[0X
    [4Xrec( attributes := [ [ "call_id", "3" ] ], object := [ 1, 3 ] )[0X
    [4Xgap> OMPutProcedureCall( stream, "retrieve", [0X
    [4X>       rec( object := [ G ], [0X
    [4X>        attributes := [ [ "call_id", "4" ] ] ) );[0X
    [4Xtrue[0X
    [4Xgap> SCSCPwait( stream );[0X
    [4Xgap> OMGetObjectWithAttributes( stream );[0X
    [4Xrec( attributes := [ [ "call_id", "4" ] ], [0X
    [4X  object := Group([ (1,2,3), (1,2) ]) )[0X
    [4Xgap> CloseStream(stream);[0X
    [4X[0X
  [4X------------------------------------------------------------------[0X
  
  After the stream is closed, it is no longer possible to retrieve the group G
  again or use it as an argument.
  
  Thus,  the  usage  of  remote  objects existing during a session reduces the
  network  traffic,  since  we pass only references instead of actual [5XOpenMath[0m
  representation  of  an  object.  Also,  the  remote object on the server may
  accumulate  certain  information in its properties and attributes, which may
  not be included in it default [5XOpenMath[0m representation.
  
  Now  we  show remote objects which remain alive after the session is closed.
  Such remote objects may be accessed later, for example, by:
  
  --    subsequent  procedure  calls  from the same instance of [5XGAP[0m or another
        system;
  
  --    other  instances  of  [5XGAP[0m  or another systems (if the identifier of an
        object is known)
  
  --    another  [5XSCSCP[0m servers which obtained a reference to such object as an
        argument of a procedure call.
  
  [1X6.2-1 StoreAsRemoteObjectPersistently[0m
  
  [2X> StoreAsRemoteObjectPersistently( [0X[3Xobj, server, port[0X[2X ) _____________[0Xfunction
  [2X> StoreAsRemoteObject( [0X[3Xobj, server, port[0X[2X ) _________________________[0Xfunction
  [6XReturns:[0X  remote object
  
  Returns the remote object corresponding to the object created at [3Xserver[0m[10X:[0m[3Xport[0m
  from  the [5XOpenMath[0m representation of the first argument [3Xobj[0m. The second form
  is just a synonym.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4X[0X
    [4Xgap> s:=StoreAsRemoteObject( SymmetricGroup(3), "localhost", 26133 );[0X
    [4X#I  Creating a socket ...[0X
    [4X#I  Connecting to a remote socket via TCP/IP ...[0X
    [4X#I  Got connection initiation message [0X
    [4X#I  Request sent ...[0X
    [4X#I  Waiting for reply ...[0X
    [4X< remote object TEMPVarSCSCP@localhost:26133 >[0X
    [4X[0X
  [4X------------------------------------------------------------------[0X
  
  Internally,  the remote object carries all the information which is required
  to get access to the original object: its identifier, server and port:
  
  [4X---------------------------  Example  ----------------------------[0X
    [4X[0X
    [4Xgap> s![1]; [0X
    [4X"TEMPVarSCSCP"[0X
    [4Xgap> s![2];[0X
    [4X"localhost"[0X
    [4Xgap> s![3];[0X
    [4X26133[0X
    [4X[0X
  [4X------------------------------------------------------------------[0X
  
  When  the  remote object is printed in the [5XOpenMath[0m format, we use symbols [10X@[0m
  and [10X:[0m to combine these parameters in the [5XOpenMath[0m reference:
  
  [4X---------------------------  Example  ----------------------------[0X
    [4X[0X
    [4Xgap> OMPrint(s);[0X
    [4X<OMOBJ>[0X
    [4X	<OMR xref="TEMPVarSCSCP@localhost:26133" />[0X
    [4X</OMOBJ>[0X
    [4X[0X
  [4X------------------------------------------------------------------[0X
  
  This  allows substitution of remote object as arguments into procedure calls
  in the same manner like we do this with usual objects:
  
  [4X---------------------------  Example  ----------------------------[0X
    [4X[0X
    [4Xgap> EvaluateBySCSCP("WS_IdGroup",[s],"localhost",26133);  [0X
    [4X#I  Creating a socket ...[0X
    [4X#I  Connecting to a remote socket via TCP/IP ...[0X
    [4X#I  Got connection initiation message [0X
    [4X#I  Request sent ...[0X
    [4X#I  Waiting for reply ...[0X
    [4Xrec( object := [ 6, 1 ], attributes := [ [ "call_id", "localhost:26133:6726" ] ] )[0X
    [4X[0X
  [4X------------------------------------------------------------------[0X
  
  [1X6.2-2 IsRemoteObject[0m
  
  [2X> IsRemoteObject______________________________________________________[0Xfilter
  
  This is the category of remote objects.
  
  [1X6.2-3 RemoteObjectsFamily[0m
  
  [2X> RemoteObjectsFamily_________________________________________________[0Xfamily
  
  This is the familty of remote objects.
  
  [1X6.2-4 RetrieveRemoteObject[0m
  
  [2X> RetrieveRemoteObject( [0X[3Xremoteobject[0X[2X ) _____________________________[0Xfunction
  [6XReturns:[0X  object
  
  This  function  retrieves  the  remote object from the remote service in the
  [5XOpenMath[0m format and constructs it locally. Note, however, that for a complex
  mathematical  object its default [5XOpenMath[0m representation may not contain all
  information  about it which was accumulated during its lifetime on the [5XSCSCP[0m
  server.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4X[0X
    [4Xgap> RetrieveRemoteObject(s);[0X
    [4X#I  Creating a socket ...[0X
    [4X#I  Connecting to a remote socket via TCP/IP ...[0X
    [4X#I  Got connection initiation message [0X
    [4X#I  Request sent ...[0X
    [4X#I  Waiting for reply ...[0X
    [4XGroup([ (1,2,3), (1,2) ])[0X
    [4X[0X
  [4X------------------------------------------------------------------[0X
  
  [1X6.2-5 UnbindRemoteObject[0m
  
  [2X> UnbindRemoteObject( [0X[3Xremoteobject[0X[2X ) _______________________________[0Xfunction
  [6XReturns:[0X  [9Xtrue[0m or [9Xfalse[0m
  
  Removes  any  value  currently  bound  to  the global variable determined by
  [3Xremoteobject[0m  at  the [5XSCSCP[0m server, and returns [9Xtrue[0m or [9Xfalse[0m dependently on
  whether this action was successful or not.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4X[0X
    [4Xgap> UnbindRemoteObject(s);[0X
    [4X#I  Creating a socket ...[0X
    [4X#I  Connecting to a remote socket via TCP/IP ...[0X
    [4X#I  Got connection initiation message [0X
    [4X#I  Request sent ...[0X
    [4X#I  Waiting for reply ...[0X
    [4Xtrue[0X
    [4X[0X
  [4X------------------------------------------------------------------[0X
  
  Finally,  we  show  an  example  when first we create a group on the service
  running  on  port 26133, and then identify it on the service running on port
  26134.  Instead  of transmitting the group to the client and then sending it
  as  an argument to the second service, the latter service directly retrieves
  the group from the first service.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4X[0X
    [4Xgap> s:=StoreAsRemoteObject( SymmetricGroup(3), "localhost", 26133 );
< remote object TEMPVarSCSCP@localhost:26133 >
gap> EvaluateBySCSCP( "WS_IdGroup", [ s ], "localhost", 26134 );
rec( object := [ 6, 1 ], attributes := [ [ "call_id", "localhost:26134:7414" ] ] )[0X
    [4X[0X
  [4X------------------------------------------------------------------[0X
  
  [4X---------------------------  Example  ----------------------------[0X
    [4X[0X
    [4Xgap> EvaluateBySCSCP("WS_IdGroup",[s],"localhost",26133 : output:="cookie" );[0X
    [4X#I  Creating a socket ...[0X
    [4X#I  Connecting to a remote socket via TCP/IP ...[0X
    [4X#I  Got connection initiation message [0X
    [4X#I  Request sent ...[0X
    [4X#I  Waiting for reply ...[0X
    [4Xrec( object := < remote object TEMPVarSCSCP2@localhost:26133 >, [0X
    [4X  attributes := [ [ "call_id", "localhost:26133:7328" ] ] )[0X
    [4X[0X
  [4X------------------------------------------------------------------[0X
  
