Message exchange by &SCSCP;

To ensure the message exchange as required by &SCSCP; specification, the &SCSCP; package extends the global record OMsymRecord from the &OpenMath; package with new entries to support &scscp1; and &scscp2; content dictionaries (, ), and also service-dependent transient private content dictionaries (see for details about transient content dictionaries). It also overwrites some &OpenMath; functions by their extended (but backwards compatible) versions, and adds some new &OpenMath;-related functions to send and receive &SCSCP; 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.

Communication with the &SCSCP; server
string
Initialises &SCSCP; session and negotiates with the server about the version of the protocol. Returns the string with the service_id (which may be used later as a part of the call identifier) or causes an error message if can not perform these tasks. gap> s := InputOutputTCPStream("localhost",26133); #I Creating a socket ... #I Connecting to a remote socket via TCP/IP ... < input/output TCP stream to localhost:26133 > gap> StartSCSCPsession(s); #I Got connection initiation message #I <?scscp service_name="GAP" service_version="4.dev" service_id="localhost:2\ 6133:5541" scscp_versions="1.0 1.1 1.2 1.3" ?> #I Requesting version 1.3 from the server ... #I Server confirmed version 1.3 to the client ... "localhost:26133:5541" After the call to the &SCSCP; server is ready to accept procedure calls.
Nothing
Takes a stream stream, the string proc&uscore;name and a record objrec, and writes to stream an &OpenMath; object procedure&uscore;call for the procedure proc&uscore;name with arguments given by the list objrec.object and procedure call options (which should be encoded as &OpenMath; attributes) given in the list objrec.attributes. This function accepts the option cd:="cdname" to specify the name of the content dictionary if the procedure is actually a standard &OpenMath; symbol note that the server may reject such a call if it accepts only calls of procedures from the transient content dictionary, see for explanation). If the cdname is not specified, scscp_transient_1 content dictionary will be assumed by default. gap> t:="";; stream:=OutputTextString(t,true);; gap> OMPutProcedureCall( stream, "WS_Factorial", rec( object:= [ 5 ], > attributes:=[ [ "call_id", "user007" ], > ["option_runtime",1000], > ["option_min_memory",1024], > ["option_max_memory",2048], > ["option_debuglevel",1], > ["option_return_object"] ] ) );; gap> Print(t); <?scscp start ?> <OMOBJ> <OMATTR> <OMATP> <OMS cd="scscp1" name="call_id"/> <OMSTR>user007</OMSTR> <OMS cd="scscp1" name="option_runtime"/> <OMI>1000</OMI> <OMS cd="scscp1" name="option_min_memory"/> <OMI>1024</OMI> <OMS cd="scscp1" name="option_max_memory"/> <OMI>2048</OMI> <OMS cd="scscp1" name="option_debuglevel"/> <OMI>1</OMI> <OMS cd="scscp1" name="option_return_object"/> <OMSTR></OMSTR> </OMATP> <OMA> <OMS cd="scscp1" name="procedure_call"/> <OMA> <OMS cd="scscp_transient_1" name="WS_Factorial"/> <OMI> 5</OMI> </OMA> </OMA> </OMATTR> </OMOBJ> <?scscp end ?>
nothing
This function may be used by the &SCSCP; client to wait (using ) until the result of the procedure call will be available from stream. 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.
record with components object and attributes, or fail
This function is similar to the function OMGetObject from the &OpenMath; package, and the main difference is that it is able to understand &OpenMath; attribution pairs. It retrieves exactly one &OpenMath; object from the stream stream, and stores it in the object component of the returned record. If the &OpenMath; object has no attributes, the attributes component of the returned record will be an empty list, otherwise it will contain pairs [attribute&uscore;name,attribute&uscore;value], where attribute&uscore;name is a string, and attribute&uscore;value is a &GAP; 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 fail instead of an error message like the function does. Returning fail is useful when OMGetObjectWithAttributes is used inside accept-evaluate-return loop.

As an example, the file scscp/tst/omdemo.om contains some &OpenMath; objects, including those from the SCSCP Specification . We can retrieve them from this file, preliminary installing some SCSCP procedures using the function :

gap> InstallSCSCPprocedure("WS_Factorial", Factorial ); gap> InstallSCSCPprocedure("GroupIdentificationService", IdGroup ); gap> InstallSCSCPprocedure("GroupByIdNumber", SmallGroup ); gap> test:=Filename( Directory( Concatenation( > GAPInfo.PackagesInfo.("scscp")[1].InstallationPath,"/tst/" ) ), > "omdemo.om" );; gap> stream:=InputTextFile(test);; gap> OMGetObjectWithAttributes(stream); rec( object := 1, attributes := [ ] ) gap> OMGetObjectWithAttributes(stream); rec( object := "Primes@localhost:26133", attributes := [ [ "call_id", "call_identifier" ] ] ) gap> OMGetObjectWithAttributes(stream); rec( object := 120, attributes := [ ] ) gap> OMGetObjectWithAttributes(stream); rec( object := [ 24, 12 ], attributes := [ [ "call_id", "alexk_9053" ], [ "option_runtime", 300000 ], [ "option_min_memory", 40964 ], [ "option_max_memory", 134217728 ], [ "option_debuglevel", 2 ], [ "option_return_object", "" ] ] ) gap> CloseStream( str );
Communication with the &SCSCP; client
nothing
Takes a stream stream, and a record objrec, and writes to stream an &OpenMath; object procedure&uscore;completed with the result being objrec.object and information messages (as &OpenMath; attributes) given in the list objrec.attributes.
gap> t:="";; stream:=OutputTextString(t,true);; gap> OMPutProcedureCompleted( stream, > rec(object:=120, > attributes:=[ [ "call_id", "user007" ] ] )); gap> Print(t); <?scscp start ?> <OMOBJ> <OMATTR> <OMATP> <OMS cd="scscp1" name="call_id"/> <OMSTR>user007</OMSTR> </OMATP> <OMA> <OMS cd="scscp1" name="procedure_completed"/> <OMI> 120</OMI> </OMA> </OMATTR> </OMOBJ> <?scscp end ?>
nothing
Takes a stream stream, and a record with an error message objrec (for example rec( attributes := [ [ "call_id", "localhost:26133:87643:gcX33cCf" ] ], object := "localhost:26133 reports : Rational operations: <divisor> must not be zero") and writes to the stream an &OpenMath; object procedure&uscore;terminated containing an error determined by the symbol error_type from the content dictionary error_cd (for example, error_memory, error_runtime or error_system_specific from the &scscp1; content dictionary ().

This is the internal function of the package which is used only in the code for the &SCSCP; server to return the error message to the client.
Example: &SCSCP; session

In the following example we start an &SCSCP; session and perform ten procedure calls in a loop before closing that session. Note that we demonstrate the usage of the session ID sid and the function RandomString from the &OpenMath; 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. gap> stream:=InputOutputTCPStream( "localhost", 26133 ); #I Creating a socket ... #I Connecting to a remote socket via TCP/IP ... < input/output TCP stream to localhost:26133 > gap> sid := StartSCSCPsession( stream ); #I Got connection initiation message #I Requesting version 1.3 from the server ... #I Server confirmed version 1.3 to the client ... "localhost:26133:5541" gap> res:=[]; [ ] gap> for i in [1..10] do > OMPutProcedureCall( stream, "WS_Factorial", > rec( object := [ i ], > attributes := [ [ "call_id", > Concatenation( sid, ":", RandomString(8) ) ] ] ) ); > SCSCPwait( stream ); > res[i]:=OMGetObjectWithAttributes( stream ).object; > od; gap> CloseStream(stream); gap> res; [ 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800 ] Also note the usage of to wait until the result of the computation will be available from stream.