]> gitweb.factorcode.org Git - factor.git/commitdiff
Fix a problem with disconnects, add a lot of features to chat server, lots of refacto...
authorDoug Coleman <erg@jobim.local>
Sat, 30 May 2009 06:29:02 +0000 (01:29 -0500)
committerDoug Coleman <erg@jobim.local>
Sat, 30 May 2009 06:29:02 +0000 (01:29 -0500)
extra/managed-server/chat/chat.factor
extra/managed-server/managed-server.factor

index 1ec22516bd93cac3c1b0f1d1a46821de91c8831b..723814bb130b4ec66a1fe233d1d3245f96722320 100644 (file)
@@ -1,23 +1,21 @@
 ! Copyright (C) 2009 Doug Coleman.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: accessors assocs combinators combinators.smart
-destructors fry io kernel managed-server namespaces
-sequences splitting unicode.case ;
+destructors fry io io.encodings.utf8 kernel managed-server
+namespaces parser sequences sorting splitting strings.parser
+unicode.case unicode.categories calendar calendar.format
+locals multiline ;
 IN: managed-server.chat
 
-CONSTANT: line-beginning "-!- "
-
 TUPLE: chat-server < managed-server ;
 
-: <chat-server> ( port -- managed-server )
-    "chat-server" chat-server new-managed-server ;
+SYMBOL: commands
+commands [ H{ } clone ] initialize
 
-: unknown-command ( string -- )
-    "Unknown command: " prepend print-client ;
+SYMBOL: chat-docs
+chat-docs [ H{ } clone ] initialize
 
-: handle-who ( string -- )
-    drop
-    clients keys ", " join print flush ;
+CONSTANT: line-beginning "-!- "
 
 : handle-me ( string -- )
     [
@@ -25,21 +23,64 @@ TUPLE: chat-server < managed-server ;
     ] "" append-outputs-as send-everyone ;
 
 : handle-quit ( string -- )
-    client [ (>>object) ] [ output-stream>> dispose ] bi ;
+    client [ (>>object) ] [ t >>quit? drop ] bi ;
+
+: handle-help ( string -- )
+    [
+        "Commands: "
+        commands get keys natural-sort ", " join append print flush
+    ] [
+        chat-docs get ?at
+        [ print flush ]
+        [ "Unknown command: " prepend print flush ] if
+    ] if-empty ;
+
+:: add-command ( quot docs key -- )
+    quot key commands get set-at
+    docs key chat-docs get set-at ;
+
+[ handle-help ]
+<" Syntax: /help [command]
+Displays the documentation for a command.">
+"help" add-command
+
+[ drop clients keys ", " join print flush ]
+<" Syntax: /who
+Shows the list of connected users.">
+"who" add-command
+
+[ drop gmt timestamp>rfc822 print flush ]
+<" Syntax: /time
+Returns the current GMT time."> "time" add-command
+
+[ handle-me ]
+<" Syntax: /me action">
+"me" add-command
+
+[ handle-quit ]
+<" Syntax: /quit [message]
+Disconnects a user from the chat server."> "quit" add-command
 
 : handle-command ( string -- )
-    " " split1 swap >lower {
-        { "who" [ handle-who ] }
-        { "me" [ handle-me ] }
-        { "quit" [ handle-quit ] }
-        [ " " glue unknown-command ]
-    } case ;
+    dup " " split1 swap >lower commands get at* [
+        call( string -- ) drop
+    ] [
+        2drop "Unknown command: " prepend print flush
+    ] if ;
+
+: <chat-server> ( port -- managed-server )
+    "chat-server" chat-server new-managed-server
+        utf8 >>encoding ;
 
 : handle-chat ( string -- )
     [
         [ username ": " ] dip
     ] "" append-outputs-as send-everyone ;
 
+M: chat-server handle-login
+    "Username: " write flush
+    readln ;
+
 M: chat-server handle-client-join
     [
         line-beginning username " has joined"
@@ -56,6 +97,7 @@ M: chat-server handle-already-logged-in
     3append print flush ;
 
 M: chat-server handle-managed-client*
-    readln [
+    readln dup f = [ t client (>>quit?) ] when
+    [
         "/" ?head [ handle-command ] [ handle-chat ] if
     ] unless-empty ;
index ad09035251439be607742ac9d3031f5640529012..4d7ede84dc42b458594d0ee4d4a7269e15cabf90 100644 (file)
@@ -11,9 +11,9 @@ TUPLE: managed-server < threaded-server clients ;
 
 TUPLE: managed-client
 input-stream output-stream local-address remote-address
-username object ;
+username object quit? ;
 
-HOOK: login threaded-server ( -- username )
+HOOK: handle-login threaded-server ( -- username )
 HOOK: handle-already-logged-in managed-server ( -- )
 HOOK: handle-client-join managed-server ( -- )
 HOOK: handle-client-disconnect managed-server ( -- )
@@ -31,16 +31,11 @@ M: managed-server handle-managed-client* ;
 : username ( -- string ) client username>> ;
 
 : send-everyone ( seq -- )
-    client-streams swap '[
+    [ client-streams ] dip '[
         output-stream>> [ _ print flush ] with-output-stream*
     ] each ;
 
-: print-client ( string -- )
-    client output-stream>>
-    [ stream-print ] [ stream-flush ] bi ;
-
 ERROR: already-logged-in username ;
-ERROR: normal-quit ;
 
 <PRIVATE
 
@@ -65,17 +60,15 @@ ERROR: normal-quit ;
     username server clients>> delete-at ;
 
 : handle-managed-client ( -- )
-    [ [ handle-managed-client* t ] loop ]
+    [ [ handle-managed-client* client quit?>> not ] loop ]
     [ delete-managed-client handle-client-disconnect ]
     [ ] cleanup ;
 
 PRIVATE>
 
-M: managed-server login readln ;
-
 M: managed-server handle-client*
     managed-server set
-    login <managed-client> managed-client set
+    handle-login <managed-client> managed-client set
     add-managed-client
     handle-client-join handle-managed-client ;