Chat server: Difference between revisions

added Ol
(Common Lisp)
(added Ol)
Line 2,230:
}
</lang>
 
=={{header|Ol}}==
<lang scheme>
(import (otus vm))
(define (timestamp) (syscall 201 "%c"))
 
(fork-server 'chat-room (lambda ()
(let this ((visitors #empty))
(let* ((envelope (wait-mail))
(sender msg envelope))
(case msg
(['join who name]
(let ((visitors (put visitors who name)))
(for-each (lambda (who)
(print-to (car who) name " joined to as"))
(ff->alist visitors))
(this visitors)))
(['talk message]
(for-each (lambda (who)
(print-to (car who) (cdr who) ": " message))
(ff->alist visitors))
(this visitors))
(['part who]
(for-each (lambda (who)
(print-to (car who) (visitors (car who) "unknown") " leaved"))
(ff->alist visitors))
(let ((visitors (del visitors who)))
(this visitors))))))))
 
 
(define (on-accept name fd)
(lambda ()
(print "# " (timestamp) "> we got new visitor: " name)
(mail 'chat-room ['join fd name])
 
(let*((ss1 ms1 (clock)))
(let loop ((str #null) (stream (force (port->bytestream fd))))
(cond
((null? stream)
#false)
((function? stream)
(mail 'chat-room ['talk (list->string (reverse str))])
(loop #null (force stream)))
(else
(loop (cons (car stream) str) (cdr stream)))))
(syscall 3 fd)
(let*((ss2 ms2 (clock)))
(print "# " (timestamp) "> visitor leave us. It takes " (+ (* (- ss2 ss1) 1000) (- ms2 ms1)) "ms.")))
(mail 'chat-room ['part fd])
))
 
(define (run port)
(let ((socket (syscall 41)))
; bind
(let loop ((port port))
(if (not (syscall 49 socket port)) ; bind
(loop (+ port 2))
(print "Server binded to " port)))
; listen
(if (not (syscall 50 socket)) ; listen
(shutdown (print "Can't listen")))
 
; accept
(let loop ()
(if (syscall 23 socket) ; select
(let ((fd (syscall 43 socket))) ; accept
;(print "\n# " (timestamp) ": new request from " (syscall 51 fd))
(fork (on-accept (syscall 51 fd) fd))))
(set-ticker-value 0)
(loop))))
 
(run 8080)
</lang>
{{Out}}
 
Usecase:
# First client connected.
# Second client connected.
# First client say "I'm the first. hello!".
# Second client say "I'm the second :)".
# Second client say "see you..".
# Second client disconnected.
# First client disconnected.
 
Server:
<pre>
$ ol chat_server.scm
Server binded to 8080
# Fri Jul 24 00:29:49 2020> we got new visitor: (127.0.0.1 . 55316)
# Fri Jul 24 00:29:55 2020> we got new visitor: (127.0.0.1 . 55320)
# Fri Jul 24 00:30:34 2020> visitor leave us. It takes 38977ms.
# Fri Jul 24 00:30:51 2020> visitor leave us. It takes 61962ms.
</pre>
 
First client:
<pre>
$ telnet 127.0.0.1 8080
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
(127.0.0.1 . 55316) joined to as
(127.0.0.1 . 55320) joined to as
I'm the first. hello!
(127.0.0.1 . 55316): I'm the first. hello!
 
(127.0.0.1 . 55316): I'm the second :)
 
(127.0.0.1 . 55316): see you..
 
(127.0.0.1 . 55316) leaved
</pre>
 
Second client:
<pre>
$ telnet 127.0.0.1 8080
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
(127.0.0.1 . 55320) joined to as
(127.0.0.1 . 55320): I'm the first. hello!
 
I'm the second :)
(127.0.0.1 . 55320): I'm the second :)
 
see you..
(127.0.0.1 . 55320): see you..
</pre>
 
 
=={{header|Perl}}==