Mercurial > lasercutter
comparison src/clojure/contrib/server_socket.clj @ 10:ef7dbbd6452c
added clojure source goodness
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 21 Aug 2010 06:25:44 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
9:35cf337adfcf | 10:ef7dbbd6452c |
---|---|
1 ;; Copyright (c) Craig McDaniel, Jan 2009. All rights reserved. | |
2 ;; The use and distribution terms for this software are covered by the | |
3 ;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) | |
4 ;; which can be found in the file epl-v10.html at the root of this distribution. | |
5 ;; By using this software in any fashion, you are agreeing to be bound by | |
6 ;; the terms of this license. | |
7 ;; You must not remove this notice, or any other, from this software. | |
8 | |
9 ;; Server socket library - includes REPL on socket | |
10 | |
11 (ns | |
12 ^{:author "Craig McDaniel", | |
13 :doc "Server socket library - includes REPL on socket"} | |
14 clojure.contrib.server-socket | |
15 (:import (java.net InetAddress ServerSocket Socket SocketException) | |
16 (java.io InputStreamReader OutputStream OutputStreamWriter PrintWriter) | |
17 (clojure.lang LineNumberingPushbackReader)) | |
18 (:use [clojure.main :only (repl)])) | |
19 | |
20 (defn- on-thread [f] | |
21 (doto (Thread. ^Runnable f) | |
22 (.start))) | |
23 | |
24 (defn- close-socket [^Socket s] | |
25 (when-not (.isClosed s) | |
26 (doto s | |
27 (.shutdownInput) | |
28 (.shutdownOutput) | |
29 (.close)))) | |
30 | |
31 (defn- accept-fn [^Socket s connections fun] | |
32 (let [ins (.getInputStream s) | |
33 outs (.getOutputStream s)] | |
34 (on-thread #(do | |
35 (dosync (commute connections conj s)) | |
36 (try | |
37 (fun ins outs) | |
38 (catch SocketException e)) | |
39 (close-socket s) | |
40 (dosync (commute connections disj s)))))) | |
41 | |
42 (defstruct server-def :server-socket :connections) | |
43 | |
44 (defn- create-server-aux [fun ^ServerSocket ss] | |
45 (let [connections (ref #{})] | |
46 (on-thread #(when-not (.isClosed ss) | |
47 (try | |
48 (accept-fn (.accept ss) connections fun) | |
49 (catch SocketException e)) | |
50 (recur))) | |
51 (struct-map server-def :server-socket ss :connections connections))) | |
52 | |
53 (defn create-server | |
54 "Creates a server socket on port. Upon accept, a new thread is | |
55 created which calls: | |
56 | |
57 (fun input-stream output-stream) | |
58 | |
59 Optional arguments support specifying a listen backlog and binding | |
60 to a specific endpoint." | |
61 ([port fun backlog ^InetAddress bind-addr] | |
62 (create-server-aux fun (ServerSocket. port backlog bind-addr))) | |
63 ([port fun backlog] | |
64 (create-server-aux fun (ServerSocket. port backlog))) | |
65 ([port fun] | |
66 (create-server-aux fun (ServerSocket. port)))) | |
67 | |
68 (defn close-server [server] | |
69 (doseq [s @(:connections server)] | |
70 (close-socket s)) | |
71 (dosync (ref-set (:connections server) #{})) | |
72 (.close ^ServerSocket (:server-socket server))) | |
73 | |
74 (defn connection-count [server] | |
75 (count @(:connections server))) | |
76 | |
77 ;;;; | |
78 ;;;; REPL on a socket | |
79 ;;;; | |
80 | |
81 (defn- socket-repl [ins outs] | |
82 (binding [*in* (LineNumberingPushbackReader. (InputStreamReader. ins)) | |
83 *out* (OutputStreamWriter. outs) | |
84 *err* (PrintWriter. ^OutputStream outs true)] | |
85 (repl))) | |
86 | |
87 (defn create-repl-server | |
88 "create a repl on a socket" | |
89 ([port backlog ^InetAddress bind-addr] | |
90 (create-server port socket-repl backlog bind-addr)) | |
91 ([port backlog] | |
92 (create-server port socket-repl backlog)) | |
93 ([port] | |
94 (create-server port socket-repl))) |