Next: , Previous: , Up: OCapN: The Object Capabilities Network   [Contents][Index]


7.3 Example: Two Goblins programs chatting over CapTP via Tor

Before diving into API details, let’s take a look at a couple of small example programs to demonstrate that this stuff works.

Here’s our client script named captp-alice.scm:

(use-modules (fibers conditions)
             (fibers operations)
             (goblins)
             (goblins ocapn ids)
             (goblins ocapn captp)
             (goblins ocapn netlayer onion)
             (ice-9 match))

;; Create a CapTP router using Tor Onion Services.
(define node-vat (spawn-vat))
(define-values (onion-netlayer private-key service-id)
  (with-vat node-vat
    (new-onion-netlayer)))
(define mycapn
  (with-vat node-vat
    (spawn-mycapn onion-netlayer)))

;; Convert the command-line argument into a sturdyref for Bob.
(define bob-uri
  (match (command-line)
    ((_ uri) uri)))
(define bob-sref (string->ocapn-id bob-uri))

;; Create a vat for Alice and enliven Bob.
(define a-vat (spawn-vat))
(define bob-vow
  (with-vat a-vat
    (<- mycapn 'enliven bob-sref)))

;; Send a message to Bob and print the response.
(define done? (make-condition))
(with-vat a-vat
  (on (<- bob-vow "Alice")
      (lambda (response)
        (format #t "Alice heard back: ~a" response)
        (signal-condition! done?))))

;; Wait until Alice has received a response before exiting.
(perform-operation (wait-operation done?))

Traditionally, Alice talks to Bob. So, now we need Bob. Save the following server script as captp-bob.scm:

(use-modules (fibers conditions)
             (fibers operations)
             (goblins)
             (goblins ocapn ids)
             (goblins ocapn captp)
             (goblins ocapn netlayer onion))

;; Bob is going to be a greeter that says hello to other people.
(define (^greeter _bcom our-name)
  (lambda (your-name)
    (format #f "Hello ~a, my name is ~a!" your-name our-name)))

;; Create Bob in their own vat.
(define b-vat (spawn-vat))
(define bob (with-vat b-vat (spawn ^greeter "Bob")))

;; Create a CapTP router using Tor Onion Services.
(define node-vat (spawn-vat))
(define-values (onion-netlayer private-key service-id)
  (with-vat node-vat
    (new-onion-netlayer)))
(define mycapn
  (with-vat node-vat
    (spawn-mycapn onion-netlayer)))

;; Create a sturdyref for Bob and print it.
(define bob-sref
  (with-vat node-vat
    ($ mycapn 'register bob 'onion)))
(format #t "Bob's sturdyref: ~a"
        (ocapn-id->string bob-sref))

;; Hold the process open indefinitely.
(perform-operation (wait-operation (make-condition)))

Okay, time to try it out! Open up two terminals, and in the first one run:

guile captp-bob.scm

This will print out a captp “sturdyref” URI to the terminal. Copy it and paste it in the second terminal as the argument to guile captp-alice.scm:

guile captp-alice.scm <STURDYREF-GOES-HERE>

Tor Onion Services can take awhile to establish, but after a short wait you should see:

Alice heard back: Hello Alice, my name is Bob!

If you see the same output then your connection succeeded! Yay! The next sections will get into the details of how to use the CapTP API.


Next: Using the CapTP API, Previous: Launching a Tor daemon for Goblins, Up: OCapN: The Object Capabilities Network   [Contents][Index]