Skip to content

Commit e69cb21

Browse files
committed
Add websocket-keepalive middleware
1 parent b3180df commit e69cb21

File tree

2 files changed

+72
-4
lines changed

2 files changed

+72
-4
lines changed
Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,47 @@
1-
(ns ring.middleware.websocket-keepalive)
1+
(ns ring.middleware.websocket-keepalive
2+
(:require [ring.websocket :as ws]
3+
[ring.websocket.protocols :as wsp])
4+
(:import [java.util.concurrent
5+
Executors Future ScheduledExecutorService TimeUnit]))
6+
7+
(def default-schedule-executor
8+
(delay (Executors/newSingleThreadScheduledExecutor)))
9+
10+
(defn websocket-keepalive-response [response options]
11+
(if (ws/websocket-response? response)
12+
(let [listener (::ws/listener response)
13+
executor (:executor options @default-schedule-executor)
14+
period (:period options 30000)
15+
task (promise)]
16+
(assoc response ::ws/listener
17+
(reify wsp/Listener
18+
(on-open [_ socket]
19+
(deliver task (.scheduleAtFixedRate
20+
^ScheduledExecutorService executor
21+
#(ws/ping socket)
22+
period period TimeUnit/MILLISECONDS))
23+
(wsp/on-open listener socket))
24+
(on-message [_ socket message]
25+
(wsp/on-message listener socket message))
26+
(on-pong [_ socket data]
27+
(wsp/on-pong listener socket data))
28+
(on-error [_ socket throwable]
29+
(wsp/on-error listener socket throwable))
30+
(on-close [_ socket code reason]
31+
(.cancel ^Future @task false)
32+
(wsp/on-close listener socket code reason))
33+
wsp/PingListener
34+
(on-ping [_ socket data]
35+
(if (satisfies? wsp/PingListener listener)
36+
(wsp/on-ping listener socket data)
37+
(wsp/-ping socket data))))))
38+
response))
39+
40+
(defn wrap-websocket-keepalive [handler options]
41+
(fn
42+
([request]
43+
(websocket-keepalive-response (handler request) options))
44+
([request respond raise]
45+
(handler request
46+
#(respond (websocket-keepalive-response % options))
47+
raise))))
Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,28 @@
11
(ns ring.middleware.websocket-keepalive-test
22
(:require [clojure.test :refer [deftest is]]
3-
[ring.middleware.websocket-keepalive :as keepalive]))
3+
[ring.websocket :as ws]
4+
[ring.websocket.protocols :as wsp]
5+
[ring.middleware.websocket-keepalive :as ka]))
46

5-
(deftest a-test
6-
(is (= 0 1)))
7+
(deftest test-websocket-keepalive-request
8+
(let [ping-count (atom 0)
9+
socket (reify wsp/Socket
10+
(-open? [_] true)
11+
(-send [_ _])
12+
(-ping [_ _] (swap! ping-count inc))
13+
(-pong [_ _])
14+
(-close [_ _ _]))
15+
response {::ws/listener
16+
(reify wsp/Listener
17+
(on-open [_ _])
18+
(on-message [_ _ _])
19+
(on-pong [_ _ _])
20+
(on-error [_ _ _])
21+
(on-close [_ _ _ _]))}
22+
response' (ka/websocket-keepalive-response response {:period 10})
23+
listener (::ws/listener response')]
24+
(wsp/on-open listener socket)
25+
(Thread/sleep 51)
26+
(wsp/on-close listener socket 1000 "")
27+
(Thread/sleep 30)
28+
(is (= @ping-count 5))))

0 commit comments

Comments
 (0)