[racket] RPC client/server (was: Limiting net-repl provided functions)
To setup a RPC client/server system, I ended up tweaking Matthew's example
from "More: Systems Programming with Racket", now that I understood better
what was needed.
http://docs.racket-lang.org/pdf/more.pdf
Below is the actual code, in case somebody else finds it useful (tested in
Linux env. only). To filter out illegal functions, I'll propably create a
list predicates and test them one by one against the rpc candidate. Overall,
this seems promising for building further Liitin proof-of-concepts. Please,
let me know if you find anything critical or a place for improvement in the
code.
Once again, thank you everyone for all the help!!
br, jukka
| J U K K A T U O M I N E N
| m a n a g i n g d i r e c t o r M. A.
|
| Finndesign Kauppiaankatu 13, FI-00160 Helsinki, Finland
| mobile +358 50 5666290
| jukka.tuominen at finndesign.fi www.finndesign.fi
-------------------------------------
#lang racket
;XXX SERVER SIDE XXX
(define server-name "localhost")
(define server-port 9877)
(define max-allow-wait 20); max concurrent clients waiting for turn
(define reuse? #f)
(define time-limit 10); secs for each rpc request
(define (allowed? expr);; Filter out illegal requests here
#t)
(define (run-rpc-server)
(define (accept-and-handle listener)
(define cust (make-custodian))
(custodian-limit-memory cust (* 50 1024 1024))
(parameterize ((current-custodian cust))
(define expr "")
(define-values (client->me me->client) (tcp-accept listener))
(thread (lambda ()
(set! expr (read client->me))
(if (allowed? expr)
(write (eval expr) me->client)
(error "Illegal procedure call!" me->client))
(close-output-port me->client)
(close-input-port client->me))))
(thread (lambda () ;; Watcher thread
(sleep time-limit)
(custodian-shutdown-all cust))))
(define main-cust (make-custodian))
(parameterize ((current-custodian main-cust))
(define listener (tcp-listen server-port max-allow-wait reuse? #f))
(define (loop)
(accept-and-handle listener)
(loop))
(thread loop))
(lambda ()
(custodian-shutdown-all main-cust)))
;XXX CLIENT SIDE XXX
;(define server-name "localhost")
;(define server-port 9877)
(define (rpc server-name expr); using default port
(let-values (((server->me me->server)
(tcp-connect server-name server-port)))
(write expr me->server)-
(close-output-port me->server)
(let ((response (read server->me)))
(close-input-port server->me)
response)))
;XXX TEST RUN XXX
(run-rpc-server)
(rpc "localhost" '(+ 1 2 3))
(+ 5 (rpc "localhost" '(+ 1 2 3)) ); combine local with remote