author: Patrick Philipot date: 9-feb-2002 version: 1.0
This little document is a "Hello world" style way to discover Rugby. Its main goal is to allow any reboller to experiment with Rugby very quickly. It is based on my own experimentation.
Rugby allows you to use rebol functions that are stored on another machine as if they where on your own computer. Turned the other way, Rugby makes available functions from one computer: the Server to others: the Clients. Rugby lets you do that in two ways :
All my experiments have been conducted under Windows. Transposition to other systems should be trivial.
The prerequisites in fact are minimal :
I will call one computer the Client, while the other is the Server. The Server will host the function for the Client. Both machines have different IP address. These are mine :
Client: | 192.168.1.52 |
Server: | 192.168.1.51 |
With Windows, the connexion is checked with the ping.exe program on the console.
ping 192.168.1.51
Results look like this (my ping speaks french).
Réponse de 192.168.1.51 : octets=32 temps=1 ms TTL=128 ... Statistiques Ping pour 192.168.1.51: Paquets : envoyés = 4, reçus = 4, perdus = 0 (perte 0%), Durée approximative des boucles en milli-secondes : minimum = 0ms, maximum = 1ms, moyenne = 0ms
Everything is fine, so let's do some rebol ! Everything will be done here in console mode on both the Client and the Server
Our modest goal is to build a Rugby server that will provide to our client a single function named TRIPLE. This function expects one argument n of type integer! and returns 3 * n.
The very first thing to do on the Server is to load rugby. This will do apparently nothing which is a good sign here.
>> do %rugby.r >>
For this test, the Server is only 5 meters from my desk, but it could have been as far as you can imagine.
Still on the Server, we define the TRIPLE function which is the function we wanted to make available to the client.
>> triple: func [n [integer!]][3 * n]
We can test it as well.
>> triple 1 == 3 >> triple 3 == 9
It is now time to expose the TRIPLE function to the world. This is done with the serve function. The serve function expects a block of function names.
>>serve [triple]
Important note |
The rebol prompt do not come back after the serve command. This is normal. If you want to get back to the rebol console, just use the Escape key. However when you do that the server is no more active. |
It is time to test all this from the client side !
The very first task for the Client is to load rugby.r . It is done in exactly the same way as for the server.
>> do %rugby.r >>
Our goal is to import the TRIPLE function, which is defined on the Server. In my eyes, it is fair to test that before import the TRIPLE function is really not known. We can test that very easily.
>> triple ** Script Error: triple has no value ** Where: do-boot ** Near: triple >>
The situation will change if we can import the function. It is important now to know where the Server is (if we know its IP address). So let's do it :
>> do get-rugby-service http://192.168.1.51:8002 >>
Important note |
In the parameter http://192.168.1.51:8002 there are three informations:
|
The beauty of rugby is that now any imported function is directly available as if it was defined locally.
>> triple 15 == 45
What append if a function named triple is already defined ? it's gone ! Let see this for ourselves :
>> triple: func [s [string!]][rejoin [s s s]] >> triple "a" == "aaa" >> do get-rugby-service http://192.168.1.51:8002 >> triple "a" ** Script Error: Cannot use multiply on string! value ** Near: 3 * n >> triple 3 == 9 >>
The locally defined function has been replaced by the remote function. This can be avoided by using context.
Function name collision can be avoided by using context (rebol context is basically an object). Here we name the context "server".
>> triple: func [s [string!]][rejoin [s s s]] >> server: context get-rugby-service http://192.168.1.51:8002 >> triple "a" == "aaa" >> server/triple 3 == 9 >>
Important ! |
To avoid naming problems you should always use a context. |
What we have done here is to import the TRIPLE function. An imported functions has a local source.
Though it is remotely executed, the TRIPLE function now exists on the Client. To prove that, let's use the standard rebol source function.
>> imported-function: get in server 'triple >> source imported-function imported-function: func [n /deferred /oneway /local http-port ... ... append rugby-statement http-port do bind rugby-statement 'do] >>
Very important note |
It is important to note that the triple function here on the Client is not a copy of the triple function defined on the Server. It is mostly a function that transparently call the real function . The remote function always stays and executes only on the Server. |
To run our new test, it is necessary to restart a fresh rebol console. Our goal here is to run the TRIPLE function without importing it. The first step is to load rugby.r .
>> do %rugby.r >>
Execution of the triple function is done through the rexec function (remote exec).
>> rexec/with [triple 15] http://192.168.1.51:8002 == 45 >>
We can now verify that the TRIPLE function as no local source.
>> source triple triple: undefined >>
Until now we have only used default settings. It is time for "sortir des sentiers battus" as we says in France.
Servers use the port 8002 by default. The /with refinement can specify another port like this.
>>serve/with [triple] tcp://:9002
Note |
Notice that tcp:// is used here (on the server). This is a bit inconsistent with the http:// that is required on the client side (for example in rexec/with [triple 15] http://192.168.1.51:8002) |
This is the code for a server that serves on http port 9002
rebol [] print "rugby-core server on HTTP port 9002" do %rugby.r triple: func [n][3 * n] serve/with [triple] tcp://:9002
For rexec the port is declared with the /with refinement.
>> rexec/with [triple 15] http://192.168.1.51:9002 == 45
For get-rugby-service the port is declared with the /with refinement.
>> server: context get-rugby-service http://192.168.1.51:9002 >> server/triple 111 == 333 >>
The /deferred is to be used for non-blocking call. Rexec/deferred returns a ticket (an integer). This ticket can be used to retrieve the result with special functions :
result-available? ticket | returns true when the result is available, false if it is not |
wait-for-result ticket | wait until the result is available and returns it |
get-result ticket | return the function result |
>> ticket: server/triple/deferred 32 == 1 >> if result-available? ticket [ print get-result ticket ] 96 >> ticket: server/triple/deferred 33 == 2 >> wait-for-result ticket == 99 >>
Rugby can use encryption. This feature is only available for rebol version with security feature (such as View/pro).
This is the code for a secure server that serves on http port 9002
rebol [] print "rugby-core secure-server on HTTP port 9002" do %rugby.r triple: func [n][3 * n] secure-serve/with [triple] tcp://:9002
Sexec is the secure equivalent for rexec.
>> sexec/with [triple 15] http://192.168.1.51:9002 == 45
If the server is not in secure mode, sexec will rise an error.
>> sexec/with [triple 15] http://192.168.1.51:9002 ** User Error: Rugby server error: Unsupported function: [negotiate] ** Near: make error! rejoin ["Rugby server error: Unsupported function: " mold statement]
Rexec is still available in secure mode.
>> rexec/with [triple 15] http://192.168.1.51:9002 == 45
Access to the server can be restricted to designated client. This is the code for a server that serves only the client with IP adress [192.168.1.53].
rebol [] print "rugby-core server for 192.168.1.53 only" do %rugby.r triple: func [n][3 * n] serve/restrict [triple] [192.168.1.53]
Only Authorized clients have access.
>> rexec/with [triple 15] http://192.168.1.51:8002 == 45
An error occurs when a request is made from an unauthorized client.
>> rexec/with [triple 15] http://192.168.1.51:8002 ** User Error: Error. Target url: http://192.168.1.51:8002/ could not be retrieved. Server response: none ** Near: return to-result read/custom proxy reduce
That's it. You know enough now to experiment by yourself.
Thanks to Maarten Koopmans, author of Rugby, for making Rugby available for all.
Documentformater copyright Robert M. Münch. All Rights Reserved.
Formatted with Make-Doc-Pro Version:1.0.0 on 10-Feb-2002 at 21:22:52