50 lines
1.8 KiB
Racket
50 lines
1.8 KiB
Racket
|
#lang racket/base
|
||
|
;; Trivial example program demonstrating os2-tcp.rkt.
|
||
|
|
||
|
(require racket/set)
|
||
|
(require racket/match)
|
||
|
(require "os2.rkt")
|
||
|
(require "os2-tcp.rkt")
|
||
|
|
||
|
(define (connection-handler local-addr)
|
||
|
(transition (set) ;; of remote TcpAddresses
|
||
|
(role 'inbound-handler (topic-subscriber (tcp-channel (wild) local-addr (wild)))
|
||
|
#:state active-remotes
|
||
|
#:topic t
|
||
|
#:on-presence (match t
|
||
|
[(topic 'publisher (tcp-channel (== local-addr) _ _) #f)
|
||
|
;; Ignore loopback flow.
|
||
|
active-remotes]
|
||
|
[(topic 'publisher (tcp-channel remote-addr (== local-addr) _) #f)
|
||
|
(write `(arrived ,remote-addr)) (newline)
|
||
|
(transition (set-add active-remotes remote-addr)
|
||
|
(send-tcp-mode remote-addr local-addr 'lines)
|
||
|
(send-tcp-credit remote-addr local-addr 1))])
|
||
|
#:on-absence (match t
|
||
|
[(topic 'publisher (tcp-channel (== local-addr) _ _) #f)
|
||
|
;; Ignore loopback flow.
|
||
|
active-remotes]
|
||
|
[(topic 'publisher (tcp-channel remote-addr (== local-addr) _) #f)
|
||
|
(write `(departed ,remote-addr)) (newline)
|
||
|
(set-remove active-remotes remote-addr)])
|
||
|
[(tcp-channel remote-addr (== local-addr) (? bytes? bs))
|
||
|
(transition active-remotes
|
||
|
(send-tcp-credit remote-addr local-addr 1)
|
||
|
(for/list ([remote (in-set active-remotes)])
|
||
|
(send-message (tcp-channel local-addr remote
|
||
|
(string->bytes/utf-8
|
||
|
(format "~a: ~a~n"
|
||
|
remote-addr
|
||
|
(bytes->string/utf-8 bs)))))))])
|
||
|
(role 'outbound-handler (topic-publisher (tcp-channel local-addr (wild) (wild)))
|
||
|
#:state active-remotes)))
|
||
|
|
||
|
(define (main port)
|
||
|
(ground-vm
|
||
|
(transition 'none
|
||
|
(spawn tcp-spy)
|
||
|
(spawn tcp-driver)
|
||
|
(spawn (connection-handler (tcp-listener port))))))
|
||
|
|
||
|
(main 5999)
|