Rugby: getting started

author: Patrick Philipot
date: 9-feb-2002
version: 1.0

Contents

1. Hello rugby or rugby for dummies
2. A short introduction to Rugby
3. Prerequisites
3.1. What is needed ?
3.2. Checking the connexion
4. Exposed function
5. Setting up the server
5.1. Loading rugby.r
5.2. Providing the function to expose
5.3. Starting the server
6. The client
6.1. Loading rugby.r
6.2. Importing function
6.3. Using imported function
6.4. Function name collision
6.5. Using context
7. Remote execution vs import
7.1. An imported function has a local source
7.2. Executing without importing with rexec
7.2.1. Loading rugby.r
7.2.2. Rexecuting functions
7.2.3. Rexecuted functions have no local source
8. Getting off-road
8.1. Serving with ...
8.2. Rexec with
8.3. Get-rugby-service with
9. Non-blocking call
10. Security
10.1. Secure-serve
10.2. Sexec
10.3. Serving specific client
11. The end

1. Hello rugby or rugby for dummies

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.


2. A short introduction to Rugby

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 :


3. Prerequisites

All my experiments have been conducted under Windows. Transposition to other systems should be trivial.

3.1. What is needed ?

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

3.2. Checking the connexion

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


4. Exposed function

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.


5. Setting up the server

5.1. Loading rugby.r

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.

5.2. Providing the function to expose

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

5.3. Starting the server

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 !


6. The client

The very first task for the Client is to load rugby.r . It is done in exactly the same way as for the server.

6.1. Loading rugby.r

>> do %rugby.r
>>

6.2. Importing function

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:
  1. The HTTP protocol is used.
  2. The IP address of the server is 192.168.1.51 .
  3. Data are exchanged through the port 8002.

6.3. Using imported function

The beauty of rugby is that now any imported function is directly available as if it was defined locally.

>> triple 15
== 45

6.4. Function name collision

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.

6.5. 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.


7. Remote execution vs import

What we have done here is to import the TRIPLE function. An imported functions has a local source.

7.1. An imported function 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.

7.2. Executing without importing with rexec

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 .

7.2.1. Loading rugby.r

>> do %rugby.r
>>

7.2.2. Rexecuting functions

Execution of the triple function is done through the rexec function (remote exec).

>> rexec/with [triple 15] http://192.168.1.51:8002
== 45
>>

7.2.3. Rexecuted functions have no local source

We can now verify that the TRIPLE function as no local source.

>> source triple
triple: undefined
>>

8. Getting off-road

Until now we have only used default settings. It is time for "sortir des sentiers battus" as we says in France.

8.1. Serving with ...

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

8.2. Rexec with

For rexec the port is declared with the /with refinement.

>> rexec/with [triple 15] http://192.168.1.51:9002
== 45

8.3. Get-rugby-service with

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
>>

9. Non-blocking call

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? ticketreturns true when the result is available, false if it is not
wait-for-result ticketwait until the result is available and returns it
get-result ticketreturn 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
>>

10. Security

Rugby can use encryption. This feature is only available for rebol version with security feature (such as View/pro).

10.1. Secure-serve

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

10.2. Sexec

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

10.3. Serving specific client

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

11. The end

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