Skip to content
Browse files

Initial commit.

  • Loading branch information...
0 parents commit edadcfc054b3ef9c7bcc99527fe32d65750e4561 @technomancy committed Oct 18, 2011
Showing with 112 additions and 0 deletions.
  1. +8 −0 .gitignore
  2. +10 −0 README.md
  3. +2 −0 project.clj
  4. +92 −0 src/server/socket.clj
8 .gitignore
@@ -0,0 +1,8 @@
+/pom.xml
+*jar
+/lib
+/classes
+/native
+/.lein-failures
+/checkouts
+/.lein-deps-sum
10 README.md
@@ -0,0 +1,10 @@
+# server-socket
+
+Server socket library from clojure-contrib, spun out into an
+independent library for compatibility with Clojure 1.3.
+
+## License
+
+Copyright © Craig McDaniel, Jan 2009
+
+Distributed under the Eclipse Public License, the same as Clojure.
2 project.clj
@@ -0,0 +1,2 @@
+(defproject server-socket "1.0.0"
+ :description "Craig McDaniel's server-socket library from old contrib.")
92 src/server/socket.clj
@@ -0,0 +1,92 @@
+;; Copyright (c) Craig McDaniel, Jan 2009. All rights reserved.
+;; The use and distribution terms for this software are covered by the
+;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+;; which can be found in the file COPYING at the root of this distribution.
+;; By using this software in any fashion, you are agreeing to be bound by
+;; the terms of this license.
+;; You must not remove this notice, or any other, from this software.
+
+(ns server.socket
+ "Server socket library - includes REPL on socket
+
+ Copyright (c) Craig McDaniel, Jan 2009. All rights reserved.
+ Extracted from clojure.contrib.server-socket as a standalone library."
+ (:import (java.net InetAddress ServerSocket Socket SocketException)
+ (java.io InputStreamReader OutputStream
+ OutputStreamWriter PrintWriter)
+ (clojure.lang LineNumberingPushbackReader))
+ (:use [clojure.main :only (repl)]))
+
+(defn- on-thread [f]
+ (doto (Thread. ^Runnable f)
+ (.start)))
+
+(defn- close-socket [^Socket s]
+ (when-not (.isClosed s)
+ (doto s
+ (.shutdownInput)
+ (.shutdownOutput)
+ (.close))))
+
+(defn- accept-fn [^Socket s connections fun]
+ (let [ins (.getInputStream s)
+ outs (.getOutputStream s)]
+ (on-thread #(do
+ (dosync (commute connections conj s))
+ (try
+ (fun ins outs)
+ (catch SocketException e))
+ (close-socket s)
+ (dosync (commute connections disj s))))))
+
+(defstruct server-def :server-socket :connections)
+
+(defn- create-server-aux [fun ^ServerSocket ss]
+ (let [connections (ref #{})]
+ (on-thread #(when-not (.isClosed ss)
+ (try
+ (accept-fn (.accept ss) connections fun)
+ (catch SocketException e))
+ (recur)))
+ (struct-map server-def :server-socket ss :connections connections)))
+
+(defn create-server
+ "Creates a server socket on port. Upon accept, a new thread is
+ created which calls:
+
+ (fun input-stream output-stream)
+
+ Optional arguments support specifying a listen backlog and binding
+ to a specific endpoint."
+ ([port fun backlog ^InetAddress bind-addr]
+ (create-server-aux fun (ServerSocket. port backlog bind-addr)))
+ ([port fun backlog]
+ (create-server-aux fun (ServerSocket. port backlog)))
+ ([port fun]
+ (create-server-aux fun (ServerSocket. port))))
+
+(defn close-server [server]
+ (doseq [s @(:connections server)]
+ (close-socket s))
+ (dosync (ref-set (:connections server) #{}))
+ (.close ^ServerSocket (:server-socket server)))
+
+(defn connection-count [server]
+ (count @(:connections server)))
+
+ ;;; REPL on a socket
+
+(defn- socket-repl [ins outs]
+ (binding [*in* (LineNumberingPushbackReader. (InputStreamReader. ins))
+ *out* (OutputStreamWriter. outs)
+ *err* (PrintWriter. ^OutputStream outs true)]
+ (repl)))
+
+(defn create-repl-server
+ "create a repl on a socket"
+ ([port backlog ^InetAddress bind-addr]
+ (create-server port socket-repl backlog bind-addr))
+ ([port backlog]
+ (create-server port socket-repl backlog))
+ ([port]
+ (create-server port socket-repl)))

0 comments on commit edadcfc

Please sign in to comment.
Something went wrong with that request. Please try again.