Introduction

Bokbok is a toolkit for exposing and consuming APIs between processes. It supports: * TCP or UNIX-domain sockets * Optional encryption and authentication (with pre-shared keys) * Multithreading over a single connection: multiple threads may make requests via the same connection, and multiple request handlers can be running at once in their own threads. * Connections are symmetrical once established: either side may invoke the other side's API at any time, "client" and "server" are just a matter of who sat passively waiting for a connection and who initiated it.

Usage

$ chicken-install bokbok

As a client

(use bokbok)

;; Called if server sends us a callback request
(define (request-handler con request)
  (match request
   (("callback" num)
     (printf "Callback received: ~s\n" num))
   (else (error "Unrecognised callback"))))

;; Called if server closes the connection
(define (close-handler con)
  (void))

(define con (open-connection '(tcp "myserver" 12345)
             "myuser" (passphrase->key "mypassphrase")
             request-handler close-handler))

(printf "Response is ~s\n" (request! con '("ping" "12345")))

(printf "Response is ~s\n" (request! con '("asynch")))

;; Wait for asynch responses to all arrive
(thread-sleep! 10)

(close-connection! con)

As a server

(use bokbok)
(use matchable)

(define *server* #f)

(define (user->key username)
  (match username
   ("myuser" (passphrase->key "mypassphrase"))
   (else #f)))

(define (open-handler con)
  (printf "CONNECTION from ~a@~s\n"
    (connection-user con)
    (connection-addr con))
  (void))

(define (request-handler con request)
  (match request
    (("ping" string)
     (list "pong" string))
    (("asynch")
     (thread-start!
       (make-thread
         (lambda ()
           (request! con '("callback" "1"))
           (thread-sleep! 1)
           (request! con '("callback" "2"))
           (thread-sleep! 1)
           (request! con '("callback" "3"))
           (thread-sleep! 1)
           (request! con '("callback" "4")))))
     ;; Return this while the callback thread runs in the background
     (list "ok"))
    (("shutdown-server!")
     (stop-server! *server*))
    (else (error "Unknown request" request))
  ))

(define (close-handler con)
  (printf "DISCONNECTION from ~a@~s\n"
    (connection-user con)
    (connection-addr con))
  (void))

(set! *server* (start-server '(tcp #f 12345) 10 user->key
   open-handler request-handler close-handler)

(wait-until-0server-stopped server)