-
-
Save bjering/bd04ff4594a3f5413bf2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns chat.session | |
(:use | |
[clojure.contrib.def]) | |
(:require | |
[chat.common] | |
[chat.session] | |
[chat.user]) | |
(:import | |
[java.net InetSocketAddress] | |
[java.util.concurrent Executors] | |
[org.jboss.netty.bootstrap ServerBootstrap] | |
[org.jboss.netty.channel Channels ChannelPipelineFactory SimpleChannelHandler] | |
[org.jboss.netty.channel.group DefaultChannelGroup] | |
[org.jboss.netty.channel.socket.nio NioServerSocketChannelFactory] | |
[org.jboss.netty.buffer ChannelBuffers] | |
[org.jboss.netty.handler.codec.frame DelimiterBasedFrameDecoder Delimiters])) | |
;helpers | |
(defn encode | |
"Creates a buffer prepared for a Flash XMLSocket" | |
[str] | |
(ChannelBuffers/wrappedBuffer | |
(into-array | |
[(.getBytes str "UTF-8") | |
(byte-array [(byte 0)])]))) | |
(def flash-policy-file | |
(str "<?xml version=\"1.0\"?>" | |
"<!DOCTYPE cross-domain-policy SYSTEM \"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd\">" | |
"<cross-domain-policy>" | |
"<allow-access-from domain=\"195.198.115.136\" to-ports=\"4711\"/>" | |
"</cross-domain-policy>")) | |
(defn- login | |
[this user-name] | |
(let | |
[user (@chat.user/users user-name)] | |
(if user | |
(chat.common/login this user) | |
(str "error No such user: [" user-name "]" )))) | |
(defn- handle-message | |
[this msg] | |
(let | |
[msg-seq (.split #" " msg) | |
command (first msg-seq) | |
args (rest msg-seq)] | |
(cond | |
(= "login" command) (apply login this args) | |
:else (str "error Unknown Command: " command)))) | |
(defn- session-parse | |
[this msg] | |
(cond | |
(.isEmpty msg) "error Empty Message" | |
(= '<' (get msg 0)) flash-policy-file | |
:else (handle-message this msg))) | |
(defn- receive | |
[this msg] | |
(let | |
[user (this :user) | |
reply (if user | |
(user :parse msg) | |
(session-parse this msg))] | |
(when reply | |
(do | |
(this :write reply))))) | |
(defn- write | |
[this msg] | |
(let | |
[netty-channel ((this :state) :netty-channel)] | |
(when (.isOpen netty-channel) | |
(.write netty-channel (encode msg))))) | |
(defn- disconnect | |
[this] | |
(let | |
[user (this :user)] | |
(when user | |
(user :send :logout)))) | |
(defn dispatcher | |
[agt message & args] | |
(let | |
[this (partial dispatcher agt)] | |
(cond | |
(= message :agent) agt | |
(= message :state) @agt | |
(= message :user) (@agt :user) | |
(= message :receive) (apply receive this args) | |
(= message :write) (apply write this args) | |
(= message :disconnect) (apply disconnect this args) | |
(= message :send) | |
(do | |
(apply chat.common/send-message agt args) | |
this) | |
:else (throw (IllegalArgumentException. | |
(str "unknown message in [" "session" "] " message)))))) | |
(defn- set-user | |
[session user] | |
(conj session {:user user})) | |
(defn- close | |
[session] | |
(let | |
[netty-channel (session :netty-channel)] | |
(when (.isOpen netty-channel) | |
(.close netty-channel)) | |
(conj session {:user nil}))) | |
(defn create | |
[netty-channel] | |
(partial dispatcher | |
(agent | |
{:netty-channel netty-channel | |
:user nil | |
:set-user set-user | |
:close close}))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment