3 Data Flow
3.1 Socket
(require neuron/socket) | package: neuron-lib |
A socket is the local end of a bi-directional serial communications channel. Each socket holds an input port and an output port.
A socket can be used as a synchronizable event. A socket is
ready for synchronization when the ports it holds have closed. Sockets
do not support half-open connections—
procedure
in-port : input-port? out-port : output-port?
procedure
(close-socket sock) → void?
sock : socket?
procedure
(socket-closed? sock) → boolean?
sock : socket?
procedure
(null-socket) → socket?
procedure
(byte-socket [#:in str #:out out?]) → socket?
str : bytes? = #"" out? : boolean? = #f
procedure
(string-socket [#:in str #:out out?]) → socket?
str : string? = "" out? : boolean? = #f
> (define sock (string-socket #:in "123" #:out #t)) > (read sock) 123
> (write 'abc sock) > (get-output-string sock) "abc"
procedure
(file-socket [ #:in in-path #:in-mode in-mode-flag #:out out-path #:out-mode out-mode-flag] #:exists exists-flag) → socket? in-path : (or/c path-string? #f) = #f in-mode-flag : (or/c 'binary 'text) = 'binary out-path : (or/c path-string? #f) = #f out-mode-flag : (or/c 'binary 'text) = 'binary
exists-flag :
(or/c 'error 'append 'update 'can-update 'replace 'truncate 'must-truncate 'truncate/replace)
See open-input-file for details on in-mode-flag, and open-output-file for details on out-mode-flag and exists-flag.
3.2 Codec
(require neuron/codec) | package: neuron-lib |
A codec is a stream that uses a socket to exchange serializable values with remote agents. The sink is called an encoder; it uses a printer procedure to serialize values to a socket. The source is called a decoder; it uses a parser procedure to de-serialize values from a socket.
Parses and emits values from a socket. Stops when prs returns eof. Closes the socket when it stops. Dies when the socket closes.
Commands:
'parser – returns prs
'socket – returns a socket
> (define dec ((decoder read) (string-socket #:in "123 abc"))) > (recv dec) 123
> (recv dec) 'abc
> (recv dec) #<eof>
Takes and prints values to a socket. Stops when it takes eof. Closes the socket when it stops. Dies when the socket closes.
Commands:
'printer – returns prn
'socket – returns a socket
> (define enc ((encoder writeln) (string-socket #:out #t))) > (for-each (curry give enc) (list 123 'abc eof)) > (get-output-string (enc 'socket)) "123\nabc\n"
Takes and prints values to a socket. Reads and emits values from a socket. Stops when given eof or prs returns eof. Closes the socket when it stops. Dies when the socket closes.
Commands:
'decoder – returns a decoder based on prs
'encoder – returns an encoder based on prn
'socket – returns a socket
> (define cdc ((codec read writeln) (string-socket #:in "123 abc" #:out #t))) > (for-each (curry give cdc) (list 987 'zyx eof)) > (recv cdc) 123
> (recv cdc) 'abc
> (recv cdc) #<eof>
> (get-output-string (cdc 'socket)) "987\nzyx\n"
3.2.1 Codec Types
A codec type is a set of uniformly-named procedures for making codecs and codec parts. A complete codec type named name is defined by the following procedures:
name-parser : parser/c
name-printer : printer/c
name-decoder : codec/c
name-encoder : codec/c
name-codec : codec/c
procedure
(make-codec-type name prs prn) →
codec/c codec/c codec/c name : symbol? prs : parser/c prn : printer/c
The result of make-codec-type is three values:
a procedure that makes decoders based on prs,
a procedure that makes encoders based on prn,
a procedure that makes codecs based on prs and prn.
syntax
(define-codec name prs prn)
A define-codec form defines 5 names:
name-parser, an alias for parser prs.
name-printer, an alias for printer prn.
name-decoder, a procedure that makes decoders based on prs.
name-encoder, a procedure that makes encoders based on prn.
name-codec, a procedure that makes codecs based on prs and prn.
procedure
procedure
procedure
procedure
procedure
> (define cdc (line-codec (string-socket #:in "123 abc\n" #:out #t))) > (give cdc "987 zyx") #t
> (recv cdc) "123 abc"
> (get-output-string (cdc 'socket)) "987 zyx\n"
procedure
procedure
procedure
procedure
procedure
> (define cdc (sexp-codec (string-socket #:in "(#hasheq((ab . 12)) 34)" #:out #t))) > (give cdc (list 987 'zyx)) #t
> (recv cdc) '( #hasheq((ab . 12))34)
> (get-output-string (cdc 'socket)) "(987 zyx)\n"
procedure
procedure
procedure
procedure
procedure
To change how null is represented, set the json-null parameter in the JSON library.
> (require json)
> (define cdc (parameterize ([json-null 'NULL]) (json-codec (string-socket #:in "[{\"ab\":12},34,null]" #:out #t)))) > (give cdc '(98 #hasheq((zy . 76)) NULL)) #t
> (recv cdc) '( #hasheq((ab . 12))34 NULL)
> (get-output-string (cdc 'socket)) "[98,{\"zy\":76},null]\n"
3.3 Network
3.3.1 TCP
(require neuron/network/tcp) | package: neuron-lib |
A TCP socket is a socket with a TCP address.
procedure
(tcp-socket? v) → boolean?
v : any/c
procedure
(tcp-socket in-port out-port) → tcp-socket?
in-port : input-port? out-port : output-port?
procedure
(tcp-socket-address sock) →
(list/c string? port-number? string? port-number?) sock : tcp-socket?
procedure
(tcp-client hostname port-no [ local-hostname local-port-no]) → socket? hostname : string? port-no : port-number? local-hostname : (or/c string? #f) = #f local-port-no : (or/c port-number? #f) = #f
See tcp-connect for argument details.
procedure
(tcp-server port-no [ max-allow-wait reuse? hostname]) → process? port-no : listen-port-number? max-allow-wait : exact-nonnegative-integer? = 4 reuse? : any/c = #f hostname : (or/c string? #f) = #f
See tcp-listen for argument details.
Commands:
'address – returns (list hostname port-no)
procedure
(tcp-service make-codec srv [ #:on-accept on-accept #:on-drop on-drop]) → process? make-codec : codec/c srv : process? on-accept : (-> any/c process? any) = void on-drop : (-> any/c process? any) = void
Commands:
'peers – returns a list of addresses
'get addr – returns the codec associated with addr, or #f is no such codec exists
'drop addr – disconnects the TCP socket associated with addr; returns #t if addr was in use, #f otherwise