Skip to content

Commit 7169e59

Browse files
committed
Add AsyncSocket protocol
1 parent c987b71 commit 7169e59

File tree

3 files changed

+43
-5
lines changed

3 files changed

+43
-5
lines changed

ring-core/src/ring/websocket.clj

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
(-pong [socket data])
2929
(-close [socket status reason]))
3030

31+
(defprotocol AsyncSocket
32+
(-send-async [socket message succeed fail]))
33+
3134
(defprotocol TextData
3235
(->string [data]))
3336

@@ -51,8 +54,11 @@
5154
:else (throw (ex-info "message is not a valid text or binary data type"
5255
{:message message}))))
5356

54-
(defn send [socket message]
55-
(-send socket (encode-message message)))
57+
(defn send
58+
([socket message]
59+
(-send socket (encode-message message)))
60+
([socket message succeed fail]
61+
(-send-async socket (encode-message message) succeed fail)))
5662

5763
(defn ping
5864
([socket]

ring-jetty-adapter/src/ring/adapter/jetty.clj

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,17 @@
2626
Session
2727
WebSocketConnectionListener
2828
WebSocketListener
29-
WebSocketPingPongListener]
29+
WebSocketPingPongListener
30+
WriteCallback]
3031
[org.eclipse.jetty.websocket.server.config
3132
JettyWebSocketServletContainerInitializer]
3233
[jakarta.servlet AsyncContext DispatcherType AsyncEvent AsyncListener]
3334
[jakarta.servlet.http HttpServletRequest HttpServletResponse]))
3435

3536
(defn- websocket-socket [^Session session]
3637
(let [remote (.getRemote session)]
37-
(reify ws/Socket
38+
(reify
39+
ws/Socket
3840
(-send [_ message]
3941
(if (string? message)
4042
(.sendString remote message)
@@ -44,7 +46,15 @@
4446
(-pong [_ data]
4547
(.sendPong remote data))
4648
(-close [_ status reason]
47-
(.close session status reason)))))
49+
(.close session status reason))
50+
ws/AsyncSocket
51+
(-send-async [_ message succeed fail]
52+
(let [callback (reify WriteCallback
53+
(writeSuccess [_] (succeed))
54+
(writeFailed [_ ex] (fail ex)))]
55+
(if (string? message)
56+
(.sendString remote message callback)
57+
(.sendBytes remote message callback)))))))
4858

4959
(defn- websocket-listener [listener]
5060
(let [socket (volatile! nil)]

ring-jetty-adapter/test/ring/adapter/test/jetty.clj

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,28 @@
718718
(is (= [[:ping "foo"] [:pong "foo"]]
719719
@log))))
720720

721+
(testing "sending websocket messages asynchronously"
722+
(let [log (atom [])
723+
handler (constantly
724+
{::ws/listener
725+
(reify ws/Listener
726+
(on-open [_ sock]
727+
(ws/send sock "Hello"
728+
(fn [] (ws/send sock "World" (fn []) (fn [_])))
729+
(fn [_])))
730+
(on-message [_ _ _])
731+
(on-pong [_ _ _])
732+
(on-error [_ _ _])
733+
(on-close [_ _ _ _]))})]
734+
(with-server handler {:port test-port}
735+
(let [ws @(hato/websocket test-websocket-url
736+
{:on-message
737+
(fn [_ msg _] (swap! log conj (str msg)))})]
738+
(Thread/sleep 100)
739+
@(hato/close! ws)
740+
(Thread/sleep 100)))
741+
(is (= ["Hello" "World"] @log))))
742+
721743
(testing "using a map as a listener"
722744
(let [listener {:on-open (fn [s] [:on-open s])
723745
:on-message (fn [s m] [:on-message s m])

0 commit comments

Comments
 (0)