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


5.4.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 machine-vat (spawn-vat))
(define-values (onion-netlayer private-key service-id)
  (with-vat machine-vat
    (new-onion-netlayer))
(define mycapn
  (with-vat machine-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 machine-vat (spawn-vat))
(define-values (onion-netlayer private-key service-id)
  (with-vat machine-vat
    (new-onion-netlayer))
(define mycapn
  (with-vat machine-vat
    (spawn-mycapn onion-netlayer)))

;; Create a sturdyref for Bob and print it.
(define bob-sref
  (with-vat machine-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, let’s 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:

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

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


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