  
  [1X4 Message exchange by [5XSCSCP[1X[0X
  
  To ensure the message exchange as required by [5XSCSCP[0m specification, the [5XSCSCP[0m
  package extends the global record [10XOMsymRecord[0m from the [5XOpenMath[0m package with
  new  entries  to  support [5Xscscp1[0m and [5Xscscp2[0m content dictionaries ([FHKLLRa],
  [FHKLR]),  and also service-dependent transient private content dictionaries
  (see [14X5[0m for details about transient content dictionaries). It also overwrites
  some  [5XOpenMath[0m  functions  by  their  extended  (but  backwards  compatible)
  versions,  and  adds some new [5XOpenMath[0m-related functions to send and receive
  [5XSCSCP[0m messages, documented below.
  
  Note  that  functions  documented in this chapter belong to the middle-level
  interface,  and  the  user  may  find  it  more  convenient to use functions
  developed on top of them and explained in next chapters.
  
  
  [1X4.1 Communication with the [5XSCSCP[1X server[0X
  
  [1X4.1-1 StartSCSCPsession[0m
  
  [2X> StartSCSCPsession( [0X[3Xstream[0X[2X ) ______________________________________[0Xfunction
  [6XReturns:[0X  string
  
  Initialises  [5XSCSCP[0m  session and negotiates with the server about the version
  of  the  protocol. Returns the string with the [10Xservice_id[0m (which may be used
  later  as  a  part of the call identifier) or causes an error message if can
  not perform these tasks.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4X[0X
    [4Xgap> s := 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(s);[0X
    [4X#I  Got connection initiation message[0X
    [4X#I  <?scscp service_name="GAP" service_version="4.dev" service_id="localhost:2\[0X
    [4X6133:5541" scscp_versions="1.0 1.1 1.2 1.3" ?>[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:5541"[0X
    [4X[0X
  [4X------------------------------------------------------------------[0X
  
  After  the  call  to  [2XStartSCSCPsession[0m  the [5XSCSCP[0m server is ready to accept
  procedure calls.
  
  [1X4.1-2 OMPutProcedureCall[0m
  
  [2X> OMPutProcedureCall( [0X[3Xstream, proc_name, objrec[0X[2X ) __________________[0Xfunction
  [6XReturns:[0X  Nothing
  
  Takes  a stream [3Xstream[0m, the string [3Xproc_name[0m and a record [3Xobjrec[0m, and writes
  to [3Xstream[0m an [5XOpenMath[0m object [10Xprocedure_call[0m for the procedure [3Xproc_name[0m with
  arguments  given by the list [10Xobjrec.object[0m and procedure call options (which
  should   be   encoded   as   [5XOpenMath[0m   attributes)   given   in   the  list
  [10Xobjrec.attributes[0m.  This function accepts the option [10Xcd:="cdname"[0m to specify
  the  name  of the content dictionary if the procedure is actually a standard
  [5XOpenMath[0m  symbol  note  that the server may reject such a call if it accepts
  only  calls  of  procedures  from  the  transient  content  dictionary,  see
  [2XInstallSCSCPprocedure[0m  ([14X5.1-1[0m)  for  explanation).  If  the  [10Xcdname[0m  is  not
  specified, [10Xscscp_transient_1[0m content dictionary will be assumed by default.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4X[0X
    [4Xgap> t:="";; stream:=OutputTextString(t,true);;[0X
    [4Xgap> OMPutProcedureCall( stream, "WS_Factorial", rec( object:= [ 5 ], [0X
    [4X>      attributes:=[ [ "call_id", "user007" ], [0X
    [4X>                    ["option_runtime",1000],[0X
    [4X>                    ["option_min_memory",1024], [0X
    [4X>                    ["option_max_memory",2048],[0X
    [4X>                    ["option_debuglevel",1], [0X
    [4X>                    ["option_return_object"] ] ) );;[0X
    [4Xgap> Print(t);[0X
    [4X<?scscp start ?>[0X
    [4X<OMOBJ>[0X
    [4X	<OMATTR>[0X
    [4X		<OMATP>[0X
    [4X			<OMS cd="scscp1" name="call_id"/>[0X
    [4X			<OMSTR>user007</OMSTR>[0X
    [4X			<OMS cd="scscp1" name="option_runtime"/>[0X
    [4X			<OMI>1000</OMI>[0X
    [4X			<OMS cd="scscp1" name="option_min_memory"/>[0X
    [4X			<OMI>1024</OMI>[0X
    [4X			<OMS cd="scscp1" name="option_max_memory"/>[0X
    [4X			<OMI>2048</OMI>[0X
    [4X			<OMS cd="scscp1" name="option_debuglevel"/>[0X
    [4X			<OMI>1</OMI>[0X
    [4X			<OMS cd="scscp1" name="option_return_object"/>[0X
    [4X			<OMSTR></OMSTR>[0X
    [4X		</OMATP>[0X
    [4X		<OMA>[0X
    [4X			<OMS cd="scscp1" name="procedure_call"/>[0X
    [4X			<OMA>[0X
    [4X				<OMS cd="scscp_transient_1" name="WS_Factorial"/>[0X
    [4X				<OMI> 5</OMI>[0X
    [4X			</OMA>[0X
    [4X		</OMA>[0X
    [4X	</OMATTR>[0X
    [4X</OMOBJ>[0X
    [4X<?scscp end ?>[0X
    [4X[0X
  [4X------------------------------------------------------------------[0X
  
  [1X4.1-3 SCSCPwait[0m
  
  [2X> SCSCPwait( [0X[3Xstream[, timeout][0X[2X ) ___________________________________[0Xfunction
  [6XReturns:[0X  nothing
  
  This  function may be used by the [5XSCSCP[0m client to wait (using [2XIO_select[0m ([14XIO:
  IO_select[0m))  until  the  result of the procedure call will be available from
  [3Xstream[0m. By default the timeout is one hour, to specify another value give it
  as  the optional second argument in seconds. See the end of this chapter for
  the example.
  
  [1X4.1-4 OMGetObjectWithAttributes[0m
  
  [2X> OMGetObjectWithAttributes( [0X[3Xstream[0X[2X ) ______________________________[0Xfunction
  [6XReturns:[0X  record with components [10Xobject[0m and [10Xattributes[0m, or [9Xfail[0m
  
  This  function  is  similar  to  the  function [10XOMGetObject[0m from the [5XOpenMath[0m
  package,  and  the main difference is that it is able to understand [5XOpenMath[0m
  attribution  pairs. It retrieves exactly one [5XOpenMath[0m object from the stream
  [3Xstream[0m, and stores it in the [10Xobject[0m component of the returned record. If the
  [5XOpenMath[0m  object has no attributes, the [10Xattributes[0m component of the returned
  record   will   be   an   empty   list,  otherwise  it  will  contain  pairs
  [10X[attribute_name,attribute_value][0m,  where  [10Xattribute_name[0m  is  a  string, and
  [10Xattribute_value[0m  is a [5XGAP[0m object, whose type is determined by the kind of an
  attribute.  Only  attributes, defined by the SCSCP are allowed, otherwise an
  error message will be displayed.
  
  If the procedure was not successful, the function returns [9Xfail[0m instead of an
  error  message  like  the function [2XOMGetObject[0m ([14XOpenMath: OMGetObject[0m) does.
  Returning  [9Xfail[0m  is  useful  when  [10XOMGetObjectWithAttributes[0m  is used inside
  accept-evaluate-return loop.
  
  As  an example, the file [11Xscscp/tst/omdemo.om[0m contains some [5XOpenMath[0m objects,
  including those from the SCSCP Specification [FHKLLRb]. We can retrieve them
  from  this  file,  preliminary  installing  some  SCSCP procedures using the
  function [2XInstallSCSCPprocedure[0m ([14X5.1-1[0m):
  
  [4X---------------------------  Example  ----------------------------[0X
    [4X[0X
    [4Xgap> InstallSCSCPprocedure("WS_Factorial", Factorial );[0X
    [4Xgap> InstallSCSCPprocedure("GroupIdentificationService", IdGroup );[0X
    [4Xgap> InstallSCSCPprocedure("GroupByIdNumber", SmallGroup );[0X
    [4Xgap> test:=Filename( Directory( Concatenation([0X
    [4X>         GAPInfo.PackagesInfo.("scscp")[1].InstallationPath,"/tst/" ) ), [0X
    [4X>         "omdemo.om" );;[0X
    [4Xgap> stream:=InputTextFile(test);;[0X
    [4Xgap> OMGetObjectWithAttributes(stream);     [0X
    [4Xrec( object := 1, attributes := [  ] )[0X
    [4Xgap> OMGetObjectWithAttributes(stream);[0X
    [4Xrec( object := "Primes@localhost:26133", [0X
    [4X  attributes := [ [ "call_id", "call_identifier" ] ] )[0X
    [4Xgap> OMGetObjectWithAttributes(stream);[0X
    [4Xrec( object := 120, attributes := [  ] )[0X
    [4Xgap> OMGetObjectWithAttributes(stream);[0X
    [4Xrec( object := [ 24, 12 ], [0X
    [4X  attributes := [ [ "call_id", "alexk_9053" ], [ "option_runtime", 300000 ], [0X
    [4X      [ "option_min_memory", 40964 ], [ "option_max_memory", 134217728 ], [0X
    [4X      [ "option_debuglevel", 2 ], [ "option_return_object", "" ] ] )[0X
    [4Xgap> CloseStream( str );[0X
    [4X[0X
  [4X------------------------------------------------------------------[0X
  
  
  [1X4.2 Communication with the [5XSCSCP[1X client[0X
  
  [1X4.2-1 OMPutProcedureCompleted[0m
  
  [2X> OMPutProcedureCompleted( [0X[3Xstream, objrec[0X[2X ) ________________________[0Xfunction
  [6XReturns:[0X  nothing
  
  Takes a stream [3Xstream[0m, and a record [3Xobjrec[0m, and writes to [3Xstream[0m an [5XOpenMath[0m
  object   [10Xprocedure_completed[0m   with   the  result  being  [10Xobjrec.object[0m  and
  information   messages   (as   [5XOpenMath[0m   attributes)   given  in  the  list
  [10Xobjrec.attributes[0m.
  
  [4X---------------------------  Example  ----------------------------[0X
    [4X[0X
    [4Xgap> t:="";; stream:=OutputTextString(t,true);;[0X
    [4Xgap> OMPutProcedureCompleted( stream, [0X
    [4X>      rec(object:=120, [0X
    [4X>      attributes:=[ [ "call_id", "user007" ] ] ));[0X
    [4Xgap> Print(t);[0X
    [4X<?scscp start ?>[0X
    [4X<OMOBJ>[0X
    [4X	<OMATTR>[0X
    [4X		<OMATP>[0X
    [4X			<OMS cd="scscp1" name="call_id"/>[0X
    [4X			<OMSTR>user007</OMSTR>[0X
    [4X		</OMATP>[0X
    [4X		<OMA>[0X
    [4X			<OMS cd="scscp1" name="procedure_completed"/>[0X
    [4X			<OMI> 120</OMI>[0X
    [4X		</OMA>[0X
    [4X	</OMATTR>[0X
    [4X</OMOBJ>[0X
    [4X<?scscp end ?>[0X
    [4X[0X
  [4X------------------------------------------------------------------[0X
  
  [1X4.2-2 OMPutProcedureTerminated[0m
  
  [2X> OMPutProcedureTerminated( [0X[3Xstream, objrec, error_cd, error_type[0X[2X ) _[0Xfunction
  [6XReturns:[0X  nothing
  
  Takes  a  stream  [3Xstream[0m,  and  a  record  with an error message [3Xobjrec[0m (for
  example [10Xrec( attributes := [ [ "call_id", "localhost:26133:87643:gcX33cCf" ]
  ],[0m  [10Xobject := "localhost:26133 reports : Rational operations: <divisor> must
  not   be   zero")[0m   and   writes   to   the   [3Xstream[0m   an   [5XOpenMath[0m  object
  [10Xprocedure_terminated[0m containing an error determined by the symbol [3Xerror_type[0m
  from   the   content   dictionary   [3Xerror_cd[0m   (for  example,  [10Xerror_memory[0m,
  [10Xerror_runtime[0m  or  [10Xerror_system_specific[0m  from the [5Xscscp1[0m content dictionary
  ([FHKLLRa]).
  
  This  is the internal function of the package which is used only in the code
  for the [5XSCSCP[0m server to return the error message to the client.
  
  
  [1X4.3 Example: [5XSCSCP[1X session[0X
  
  In the following example we start an [5XSCSCP[0m session and perform ten procedure
  calls  in  a  loop before closing that session. Note that we demonstrate the
  usage  of the session ID [10Xsid[0m and the function [10XRandomString[0m from the [5XOpenMath[0m
  package  to  produce some unique call identifier. The call ID is a mandatory
  attribute for any procedure call, however, it is not nesessarily random; for
  example, it may be just a string with the number of the procedure call.
  
  [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> sid := 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:5541"[0X
    [4Xgap> res:=[];[0X
    [4X[  ][0X
    [4Xgap> for i in [1..10] do[0X
    [4X>     OMPutProcedureCall( stream, "WS_Factorial", [0X
    [4X>       rec( object := [ i ], [0X
    [4X>        attributes := [ [ "call_id", [0X
    [4X>          Concatenation( sid, ":", RandomString(8) ) ] ] ) );[0X
    [4X>     SCSCPwait( stream );[0X
    [4X>     res[i]:=OMGetObjectWithAttributes( stream ).object;[0X
    [4X> od;[0X
    [4Xgap> CloseStream(stream);[0X
    [4Xgap> res;[0X
    [4X[ 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800 ][0X
    [4X[0X
  [4X------------------------------------------------------------------[0X
  
  Also  note  the  usage  of [2XSCSCPwait[0m ([14X4.1-3[0m) to wait until the result of the
  computation will be available from [10Xstream[0m.
  
