1 ! Copyright (C) 2009 Doug Coleman.
2 ! See https://factorcode.org/license.txt for BSD license.
3 USING: accessors assocs continuations io io.servers io.sockets
4 kernel namespaces sequences ;
7 TUPLE: managed-server < threaded-server clients ;
10 input-stream output-stream local-address remote-address
11 username object quit? logged-in? ;
13 HOOK: handle-login threaded-server ( -- username )
14 HOOK: handle-managed-client* managed-server ( -- )
15 HOOK: handle-already-logged-in managed-server ( -- )
16 HOOK: handle-client-join managed-server ( -- )
17 HOOK: handle-client-disconnect managed-server ( -- )
19 ERROR: already-logged-in username ;
21 M: managed-server handle-already-logged-in already-logged-in ;
22 M: managed-server handle-client-join ;
23 M: managed-server handle-client-disconnect ;
25 : server ( -- managed-client ) managed-server get ;
26 : client ( -- managed-client ) managed-client get ;
27 : clients ( -- assoc ) server clients>> ;
28 : client-streams ( -- assoc ) clients values ;
29 : username ( -- string ) client username>> ;
30 : everyone-else ( -- assoc )
31 clients [ username = ] reject-keys ;
32 : everyone-else-streams ( -- assoc ) everyone-else values ;
34 ERROR: no-such-client username ;
38 : (send-client) ( managed-client seq -- )
39 [ output-stream>> ] dip '[ _ print flush ] with-output-stream* ;
43 : send-client ( seq username -- )
44 clients ?at [ no-such-client ] [ (send-client) ] if ;
46 : send-everyone ( seq -- )
47 [ client-streams ] dip '[ _ (send-client) ] each ;
49 : send-everyone-else ( seq -- )
50 [ everyone-else-streams ] dip '[ _ (send-client) ] each ;
54 : <managed-client> ( username -- managed-client )
57 input-stream get >>input-stream
58 output-stream get >>output-stream
59 local-address get >>local-address
60 remote-address get >>remote-address ;
62 : maybe-login-client ( -- )
63 username clients key? [
64 handle-already-logged-in
67 client username clients set-at
70 : when-logged-in ( quot -- )
71 client logged-in?>> [ call ] [ drop ] if ; inline
73 : delete-managed-client ( -- )
74 [ username server clients>> delete-at ] when-logged-in ;
76 : handle-managed-client ( -- )
77 handle-login <managed-client> managed-client namespaces:set
80 [ handle-managed-client* client quit?>> not ] loop
83 : cleanup-client ( -- )
86 handle-client-disconnect
91 M: managed-server handle-client*
92 managed-server namespaces:set
93 [ handle-managed-client ]
97 : new-managed-server ( port name encoding class -- server )
102 H{ } clone >>clients ; inline
104 : new-managed-server* ( encoding class -- server )
107 H{ } clone >>clients ; inline