chat.l (1254B)
1 # non-blocking chat server 2 # 3 # server: picolisp$ (chat 4444) 4 # clients: $ telnet localhost 4444 5 6 (load "nb.l") 7 8 (off *H) # handlers 9 10 (class +Handler) 11 # s [w] 12 13 (dm T (S) 14 (=: s S) 15 (=: w (new)) 16 (push '*H (cons S This)) ) 17 18 (dm rm> () 19 (prinl "q " (: s)) 20 (task (: s)) 21 (close (: s)) 22 (setq *H (delq (assoc (: s) *H) *H)) ) 23 24 (dm wr> (Who Msg) 25 (fifo (: w) (cons Who Msg)) ) 26 27 (setq *N 1024 *B (need *N)) # read buffer 28 29 (dm cb> () 30 (block (: s) NIL) 31 (let N (in (: s) (rdx *B *N)) 32 (prinl "r " (: s) " " N) 33 (cond 34 ((gt0 N) (for H *H (wr> (cdr H) S (head N *B)))) 35 ((= N (eagain))) 36 (T (rm> This)) ) ) 37 (for H *H (fl> (cdr H))) ) 38 39 (dm fl> () 40 (use X 41 (while 42 (and (setq X (cadr (val (: w)))) # peek head 43 (let (S (cdr X) 44 M (length S) 45 N (out (: s) (wrx S M))) 46 (prinl "w " (: s) " " N "/" M) 47 (when (gt0 N) 48 (if (<= M N) 49 (fifo (: w)) 50 (set (cdr (val (: w))) (tail (- M N) S)) ) ) ) ) ) ) ) 51 52 (de chat (Port) 53 (task (port Port) 54 (when (accept @) 55 (task @ 56 This (new '(+Handler) @) 57 (cb> This) ) ) ) )