|
4 | 4 | [pixie.uv :as uv] |
5 | 5 | [pixie.ffi :as ffi])) |
6 | 6 |
|
7 | | -(defrecord TCPServer [ip port on-connect uv-server bind-addr on-connection-cb]) |
| 7 | +(defrecord TCPServer [ip port on-connect uv-server bind-addr on-connection-cb] |
| 8 | + IDisposable |
| 9 | + (-dispose! [this] |
| 10 | + (uv/uv_close uv-server st/close_cb) |
| 11 | + (dispose! @on-connection-cb) |
| 12 | + (dispose! bind-addr))) |
8 | 13 |
|
9 | 14 | (defn -prep-uv-buffer-fn [buf read-bytes] |
10 | 15 | (ffi/ffi-prep-callback |
11 | 16 | uv/uv_alloc_cb |
12 | 17 | (fn [handle suggested-size uv-buf] |
13 | 18 | (try |
14 | 19 | (let [casted (ffi/cast uv-buf uv/uv_buf_t)] |
15 | | - (println "Alloc " handle suggested-size buf read-bytes) |
16 | 20 | (ffi/set! casted :base buf) |
17 | 21 | (ffi/set! casted :len (min suggested-size |
18 | 22 | (buffer-capacity buf) |
|
30 | 34 | (reset! read-cb (ffi/ffi-prep-callback |
31 | 35 | uv/uv_read_cb |
32 | 36 | (fn [stream nread uv-buf] |
33 | | - (println "-<<< nread <-- " nread) |
34 | 37 | (set-buffer-count! buffer nread) |
35 | 38 | (try |
36 | 39 | (dispose! alloc-cb) |
37 | 40 | (dispose! @read-cb) |
38 | 41 | ;(dispose! uv-buf) |
39 | 42 | (uv/uv_read_stop stream) |
40 | | - (st/run-and-process k nread) |
| 43 | + (st/run-and-process k (or |
| 44 | + (st/exception-on-uv-error nread) |
| 45 | + nread)) |
41 | 46 | (catch ex |
42 | 47 | (println ex)))))) |
43 | 48 | (uv/uv_read_start uv-client alloc-cb @read-cb))))) |
44 | 49 | IOutputStream |
45 | 50 | (write [this buffer] |
46 | 51 | (let [write-cb (atom nil) |
47 | 52 | uv_write (uv/uv_write_t)] |
48 | | - (println "writing " (count buffer)) |
49 | 53 | (ffi/set! uv-write-buf :base buffer) |
50 | 54 | (ffi/set! uv-write-buf :len (count buffer)) |
51 | 55 | (st/call-cc |
52 | 56 | (fn [k] |
53 | 57 | (reset! write-cb (ffi/ffi-prep-callback |
54 | 58 | uv/uv_write_cb |
55 | 59 | (fn [req status] |
56 | | - (println status "<<-- status") |
57 | 60 | (try |
58 | 61 | (dispose! @write-cb) |
59 | 62 | ;(uv/uv_close uv_write st/close_cb) |
60 | 63 | (st/run-and-process k status) |
61 | 64 | (catch ex |
62 | 65 | (println ex)))))) |
63 | | - (uv/uv_write uv_write uv-client uv-write-buf 1 @write-cb)))))) |
| 66 | + (uv/uv_write uv_write uv-client uv-write-buf 1 @write-cb))))) |
| 67 | + IDisposable |
| 68 | + (-dispose! [this] |
| 69 | + (dispose! uv-write-buf) |
| 70 | + (uv/uv_close uv-client st/close_cb))) |
64 | 71 |
|
65 | 72 | (defn launch-tcp-client-from-server [svr] |
66 | 73 | (assert (instance? TCPServer svr) "Requires a TCPServer as the first argument") |
|
94 | 101 | (uv/throw-on-error (uv/uv_listen server 128 @on-new-connetion)) |
95 | 102 | (st/yield-control) |
96 | 103 | tcp-server)) |
| 104 | + |
| 105 | + |
| 106 | +(defn tcp-client [ip port] |
| 107 | + (let [client-addr (uv/sockaddr_in) |
| 108 | + uv-connect (uv/uv_connect_t) |
| 109 | + client (uv/uv_tcp_t) |
| 110 | + cb (atom nil)] |
| 111 | + (uv/throw-on-error (uv/uv_ip4_addr ip port client-addr)) |
| 112 | + (uv/uv_tcp_init (uv/uv_default_loop) client) |
| 113 | + (st/call-cc (fn [k] |
| 114 | + (reset! cb (ffi/ffi-prep-callback |
| 115 | + uv/uv_connect_cb |
| 116 | + (fn [_ status] |
| 117 | + (try |
| 118 | + (dispose! @cb) |
| 119 | + (dispose! uv-connect) |
| 120 | + (dispose! client-addr) |
| 121 | + (st/run-and-process k (or (st/exception-on-uv-error status) |
| 122 | + (->TCPStream client (uv/uv_buf_t)))) |
| 123 | + (catch ex |
| 124 | + (println ex)))))) |
| 125 | + (uv/uv_tcp_connect uv-connect client client-addr @cb))) |
| 126 | + |
| 127 | + )) |
0 commit comments