A Simple Clojure IRC Client

The other night I was toying with the following script, I was going to thrash it but figured it may help someone or me later on so I am dumping it here. It doesn't do anything other then to sit idle in a channel,

( ns irc ( :import (java.net Socket) (java.io PrintWriter InputStreamReader BufferedReader))) ( def freenode { :name "irc.freenode.net" :port 6667}) ( def user { :name "Nurullah Akkaya" :nick "nakkaya" }) ( declare conn-handler) ( defn connect [server] ( let [socket (Socket. ( :name server) ( :port server)) in (BufferedReader. (InputStreamReader. (.getInputStream socket))) out (PrintWriter. (.getOutputStream socket)) conn (ref { :in in :out out})] ( doto (Thread. #(conn-handler conn)) (.start)) conn)) ( defn write [conn msg] ( doto ( :out @conn) (.println (str msg " \r " )) (.flush))) ( defn conn-handler [conn] (while (nil? ( :exit @conn)) ( let [msg (.readLine ( :in @conn))] (println msg) ( cond (re-find # "^ERROR :Closing Link:" msg) ( dosync (alter conn merge { :exit true })) (re-find # "^PING" msg) (write conn (str "PONG " (re-find # ":.*" msg))))))) ( defn login [conn user] (write conn (str "NICK " ( :nick user))) (write conn (str "USER " ( :nick user) " 0 * :" ( :name user))))

( def irc (connect freenode)) (login irc user) (write irc "JOIN #clojure" ) (write irc "QUIT" )

Lots of this code should be self-explanatory, calling connect will open a socket to the server, it will return a ref containing a reader and a writer associated with the socket, it will also spawn a new thread that will handle incoming messages from the server.

conn-handler will keep reading and printing from the socket until exit key in the conn ref is set which happens when we receive a "Closing Link" message from the server, every once in a while server will ping us with "PING :randomstring" we need to reply "PONG :randomstring" else we get disconnected. Thats all there is to it, as I said it doesn't do anything but with a few regexes you can turn it in to client or a bot.