update wrap-browserchannel arguments
passing in event handlers is obviously going to be the most common usage (all apps won't necessarily need to change the default options, though many will want to). so it seems silly to hide the event handlers as an option... i feel like it's better as it's own separate argument.
This commit is contained in:
parent
eff6566ac5
commit
f889985fe1
|
@ -39,7 +39,7 @@
|
||||||
|
|
||||||
(def handler
|
(def handler
|
||||||
(-> app-routes
|
(-> app-routes
|
||||||
(browserchannel/wrap-browserchannel {:events event-handlers})
|
(browserchannel/wrap-browserchannel event-handlers)
|
||||||
(wrap-defaults site-defaults)))
|
(wrap-defaults site-defaults)))
|
||||||
|
|
||||||
(defn run-jetty []
|
(defn run-jetty []
|
||||||
|
|
|
@ -528,7 +528,7 @@
|
||||||
;; creates a session agent wrapping session data and
|
;; creates a session agent wrapping session data and
|
||||||
;; adds the session to sessions
|
;; adds the session to sessions
|
||||||
(defn- create-session-agent
|
(defn- create-session-agent
|
||||||
[req options]
|
[req events options]
|
||||||
(let [{initial-rid "RID" ;; identifier for forward channel
|
(let [{initial-rid "RID" ;; identifier for forward channel
|
||||||
app-version "CVER" ;; client can specify a custom app-version
|
app-version "CVER" ;; client can specify a custom app-version
|
||||||
old-session-id "OSID"
|
old-session-id "OSID"
|
||||||
|
@ -573,7 +573,7 @@
|
||||||
;; when the client never connects with a backchannel
|
;; when the client never connects with a backchannel
|
||||||
(send-off session-agent refresh-session-timeout)
|
(send-off session-agent refresh-session-timeout)
|
||||||
;; register application-level browserchannel session events
|
;; register application-level browserchannel session events
|
||||||
(let [{:keys [on-open on-close on-receive]} (:events options)]
|
(let [{:keys [on-open on-close on-receive]} events]
|
||||||
(if on-close (add-listener id :close on-close))
|
(if on-close (add-listener id :close on-close))
|
||||||
(if on-receive (add-listener id :map on-receive))
|
(if on-receive (add-listener id :map on-receive))
|
||||||
(if on-open (on-open id req)))
|
(if on-open (on-open id req)))
|
||||||
|
@ -701,10 +701,10 @@
|
||||||
;; POST req client -> server is a forward channel
|
;; POST req client -> server is a forward channel
|
||||||
;; session might be nil, when this is the first POST by client
|
;; session might be nil, when this is the first POST by client
|
||||||
(defn- handle-forward-channel
|
(defn- handle-forward-channel
|
||||||
[req session-agent options]
|
[req session-agent events options]
|
||||||
(let [[session-agent is-new-session] (if session-agent
|
(let [[session-agent is-new-session] (if session-agent
|
||||||
[session-agent false]
|
[session-agent false]
|
||||||
[(create-session-agent req options) true])
|
[(create-session-agent req events options) true])
|
||||||
;; maps contains whatever the messages to the server
|
;; maps contains whatever the messages to the server
|
||||||
maps (get-maps req)]
|
maps (get-maps req)]
|
||||||
;; if maps were received in this request, we should forward to listeners
|
;; if maps were received in this request, we should forward to listeners
|
||||||
|
@ -743,7 +743,7 @@
|
||||||
|
|
||||||
;; GET req server->client is a backwardchannel opened by client
|
;; GET req server->client is a backwardchannel opened by client
|
||||||
(defn- handle-backward-channel
|
(defn- handle-backward-channel
|
||||||
[req session-agent options]
|
[req session-agent events options]
|
||||||
(let [type (get-in req [:query-params "TYPE"])
|
(let [type (get-in req [:query-params "TYPE"])
|
||||||
rid (get-in req [:query-params "RID"])]
|
rid (get-in req [:query-params "RID"])]
|
||||||
(cond
|
(cond
|
||||||
|
@ -769,7 +769,7 @@
|
||||||
;; get to /<base>/bind is client->server msg
|
;; get to /<base>/bind is client->server msg
|
||||||
;; post to /<base>/bind is initiate server->client channel
|
;; post to /<base>/bind is initiate server->client channel
|
||||||
(defn- handle-bind-channel
|
(defn- handle-bind-channel
|
||||||
[req options]
|
[req events options]
|
||||||
(let [SID (get-in req [:query-params "SID"])
|
(let [SID (get-in req [:query-params "SID"])
|
||||||
;; session-agent might be nil, then it will be created by
|
;; session-agent might be nil, then it will be created by
|
||||||
;; handle-forward-channel.
|
;; handle-forward-channel.
|
||||||
|
@ -790,8 +790,8 @@
|
||||||
(when-let [AID (get-in req [:query-params "AID"])]
|
(when-let [AID (get-in req [:query-params "AID"])]
|
||||||
(send-off session-agent acknowledge-arrays AID)))
|
(send-off session-agent acknowledge-arrays AID)))
|
||||||
(condp = (:request-method req)
|
(condp = (:request-method req)
|
||||||
:post (handle-forward-channel req session-agent options)
|
:post (handle-forward-channel req session-agent events options)
|
||||||
:get (handle-backward-channel req session-agent options))))))
|
:get (handle-backward-channel req session-agent events options))))))
|
||||||
|
|
||||||
;; straight from google
|
;; straight from google
|
||||||
(def standard-headers
|
(def standard-headers
|
||||||
|
@ -836,26 +836,21 @@
|
||||||
(defn wrap-browserchannel
|
(defn wrap-browserchannel
|
||||||
"adds browserchannel support to a ring handler.
|
"adds browserchannel support to a ring handler.
|
||||||
|
|
||||||
the most important option that all applications will want to provide
|
events should be a map of event handler functions. you only need to
|
||||||
is :events. this should be a map of event handler functions:
|
include handler functions for events you care about.
|
||||||
|
|
||||||
{:on-open (fn [session-id request] ...)
|
{:on-open (fn [session-id request] ...)
|
||||||
:on-close (fn [session-id request reason] ...)
|
:on-close (fn [session-id request reason] ...)
|
||||||
:on-receive (fn [session-id request data] ...)}
|
:on-receive (fn [session-id request data] ...)}
|
||||||
|
|
||||||
:on-open is called when new client browserchannel sessions are created.
|
|
||||||
:on-close is called when clients disconnect.
|
|
||||||
:on-receive is called when data is received from the client via the
|
|
||||||
forward channel.
|
|
||||||
|
|
||||||
for all events, request is a Ring request map and can be used to access
|
for all events, request is a Ring request map and can be used to access
|
||||||
up to date cookie or (http) session data, or other client info. you
|
up to date cookie or (http) session data, or other client info. you
|
||||||
cannot use these event handlers to update the client's (http) session
|
cannot use these event handlers to update the client's (http) session
|
||||||
data as no response is returned via these event handler functions.
|
data as no response is returned via these event handler functions.
|
||||||
|
|
||||||
for other supported options, see
|
for the supported options, see
|
||||||
net.thegeez.browserchannel.server/default-options"
|
net.thegeez.browserchannel.server/default-options"
|
||||||
[handler & [options]]
|
[handler events & [options]]
|
||||||
(let [options (merge default-options options)
|
(let [options (merge default-options options)
|
||||||
base (str (:base options))]
|
base (str (:base options))]
|
||||||
(-> (fn [req]
|
(-> (fn [req]
|
||||||
|
@ -867,7 +862,7 @@
|
||||||
(handle-test-channel req options)
|
(handle-test-channel req options)
|
||||||
|
|
||||||
(.startsWith uri (str base "/bind"))
|
(.startsWith uri (str base "/bind"))
|
||||||
(handle-bind-channel req options)
|
(handle-bind-channel req events options)
|
||||||
|
|
||||||
:else
|
:else
|
||||||
(handler req))))
|
(handler req))))
|
||||||
|
|
|
@ -25,31 +25,30 @@
|
||||||
(use-fixtures :each reset-sessions-fixture async-output-fixture)
|
(use-fixtures :each reset-sessions-fixture async-output-fixture)
|
||||||
|
|
||||||
(defn app
|
(defn app
|
||||||
[request & [options]]
|
[request & {:keys [events options]}]
|
||||||
((-> (fn [{:keys [uri] :as request}]
|
((-> (fn [{:keys [uri] :as request}]
|
||||||
(if (or (= "" uri)
|
(if (or (= "" uri)
|
||||||
(= "/" uri))
|
(= "/" uri))
|
||||||
(response/response "Hello, world!")
|
(response/response "Hello, world!")
|
||||||
(response/not-found "not found")))
|
(response/not-found "not found")))
|
||||||
(wrap-browserchannel (or options default-options))
|
(wrap-browserchannel events (or options default-options))
|
||||||
(wrap-test-async-adapter (or options default-options)))
|
(wrap-test-async-adapter (or options default-options)))
|
||||||
request))
|
request))
|
||||||
|
|
||||||
(deftest create-session-test
|
(deftest create-session-test
|
||||||
(let [options default-options
|
(let [resp (app (-> (mock/request
|
||||||
resp (app (-> (mock/request
|
|
||||||
:post "/channel/bind")
|
:post "/channel/bind")
|
||||||
(mock/query-string
|
(mock/query-string
|
||||||
{"VER" protocol-version
|
{"VER" protocol-version
|
||||||
"RID" 1
|
"RID" 1
|
||||||
"CVER" protocol-version
|
"CVER" protocol-version
|
||||||
"zx" (random-string)
|
"zx" (random-string)
|
||||||
"t" 1}))
|
"t" 1})))]
|
||||||
options)]
|
|
||||||
(wait-for-agent-send-offs)
|
(wait-for-agent-send-offs)
|
||||||
(is (= 200 (:status resp)))
|
(is (= 200 (:status resp)))
|
||||||
(is (contains-all-of? (:headers resp)
|
(is (contains-all-of?
|
||||||
(dissoc (:headers options) "Content-Type")))
|
(:headers resp)
|
||||||
|
(dissoc (:headers default-options) "Content-Type")))
|
||||||
(let [arrays (get-response-arrays (:body resp))
|
(let [arrays (get-response-arrays (:body resp))
|
||||||
[[id [c session-id host-prefix version]]] (first arrays)]
|
[[id [c session-id host-prefix version]]] (first arrays)]
|
||||||
(is (= "c" c))
|
(is (= "c" c))
|
||||||
|
@ -111,9 +110,8 @@
|
||||||
session-id))
|
session-id))
|
||||||
|
|
||||||
(deftest create-session-and-open-backchannel-test
|
(deftest create-session-and-open-backchannel-test
|
||||||
(let [options default-options
|
(let [; 1. forwardchannel request to create session
|
||||||
; 1. forwardchannel request to create session
|
create-resp (app (->new-session-request))
|
||||||
create-resp (app (->new-session-request) options)
|
|
||||||
session-id (get-session-id create-resp)
|
session-id (get-session-id create-resp)
|
||||||
; 2. backchannel request (long request, async response)
|
; 2. backchannel request (long request, async response)
|
||||||
back-resp (app (-> (mock/request
|
back-resp (app (-> (mock/request
|
||||||
|
@ -136,8 +134,9 @@
|
||||||
(is (= 200 (:status async-resp)))
|
(is (= 200 (:status async-resp)))
|
||||||
; 4. verify session is still connected, backchannel request still alive
|
; 4. verify session is still connected, backchannel request still alive
|
||||||
(is (not (:closed? async-resp)))
|
(is (not (:closed? async-resp)))
|
||||||
(is (contains-all-of? (:headers async-resp)
|
(is (contains-all-of?
|
||||||
(dissoc (:headers options) "Content-Type")))
|
(:headers async-resp)
|
||||||
|
(dissoc (:headers default-options) "Content-Type")))
|
||||||
(is (connected? session-id))
|
(is (connected? session-id))
|
||||||
(is (:has-back-channel? status)))))
|
(is (:has-back-channel? status)))))
|
||||||
|
|
||||||
|
@ -157,9 +156,8 @@
|
||||||
"t" 1})))
|
"t" 1})))
|
||||||
|
|
||||||
(deftest send-data-to-client-test
|
(deftest send-data-to-client-test
|
||||||
(let [options default-options
|
(let [; 1. forwardchannel request to create session
|
||||||
; 1. forwardchannel request to create session
|
create-resp (app (->new-session-request))
|
||||||
create-resp (app (->new-session-request) options)
|
|
||||||
session-id (get-session-id create-resp)
|
session-id (get-session-id create-resp)
|
||||||
; 2. backchannel request (long request, async response)
|
; 2. backchannel request (long request, async response)
|
||||||
back-resp (app (->new-backchannel-request session-id))]
|
back-resp (app (->new-backchannel-request session-id))]
|
||||||
|
@ -173,16 +171,16 @@
|
||||||
(is (= 200 (:status back-resp)))
|
(is (= 200 (:status back-resp)))
|
||||||
(is (= 200 (:status async-resp)))
|
(is (= 200 (:status async-resp)))
|
||||||
(is (not (:closed? async-resp)))
|
(is (not (:closed? async-resp)))
|
||||||
(is (contains-all-of? (:headers async-resp)
|
(is (contains-all-of?
|
||||||
(dissoc (:headers options) "Content-Type")))
|
(:headers async-resp)
|
||||||
|
(dissoc (:headers default-options) "Content-Type")))
|
||||||
; 5. verify data was sent
|
; 5. verify data was sent
|
||||||
(is (= (-> arrays ffirst second (get "__edn") (edn/read-string))
|
(is (= (-> arrays ffirst second (get "__edn") (edn/read-string))
|
||||||
{:foo "bar"})))))
|
{:foo "bar"})))))
|
||||||
|
|
||||||
(deftest send-multiple-data-to-client-test
|
(deftest send-multiple-data-to-client-test
|
||||||
(let [options default-options
|
(let [; 1. forwardchannel request to create session
|
||||||
; 1. forwardchannel request to create session
|
create-resp (app (->new-session-request))
|
||||||
create-resp (app (->new-session-request) options)
|
|
||||||
session-id (get-session-id create-resp)
|
session-id (get-session-id create-resp)
|
||||||
; 2. backchannel request (long request, async response)
|
; 2. backchannel request (long request, async response)
|
||||||
back-resp (app (->new-backchannel-request session-id))]
|
back-resp (app (->new-backchannel-request session-id))]
|
||||||
|
@ -197,8 +195,9 @@
|
||||||
(is (= 200 (:status back-resp)))
|
(is (= 200 (:status back-resp)))
|
||||||
(is (= 200 (:status async-resp)))
|
(is (= 200 (:status async-resp)))
|
||||||
(is (not (:closed? async-resp)))
|
(is (not (:closed? async-resp)))
|
||||||
(is (contains-all-of? (:headers async-resp)
|
(is (contains-all-of?
|
||||||
(dissoc (:headers options) "Content-Type")))
|
(:headers async-resp)
|
||||||
|
(dissoc (:headers default-options) "Content-Type")))
|
||||||
; 5. verify data was sent
|
; 5. verify data was sent
|
||||||
(is (= (get-edn-from-arrays arrays 0)
|
(is (= (get-edn-from-arrays arrays 0)
|
||||||
{:foo "bar"}))
|
{:foo "bar"}))
|
||||||
|
@ -206,9 +205,8 @@
|
||||||
"hello, world")))))
|
"hello, world")))))
|
||||||
|
|
||||||
(deftest send-data-to-client-before-backchannel-created
|
(deftest send-data-to-client-before-backchannel-created
|
||||||
(let [options default-options
|
(let [; 1. forwardchannel request to create session
|
||||||
; 1. forwardchannel request to create session
|
create-resp (app (->new-session-request))
|
||||||
create-resp (app (->new-session-request) options)
|
|
||||||
session-id (get-session-id create-resp)]
|
session-id (get-session-id create-resp)]
|
||||||
(wait-for-agent-send-offs)
|
(wait-for-agent-send-offs)
|
||||||
; 2. send data to client. no backchannel yet, so it should be queued in a buffer
|
; 2. send data to client. no backchannel yet, so it should be queued in a buffer
|
||||||
|
@ -224,16 +222,16 @@
|
||||||
(is (= 200 (:status back-resp)))
|
(is (= 200 (:status back-resp)))
|
||||||
(is (= 200 (:status async-resp)))
|
(is (= 200 (:status async-resp)))
|
||||||
(is (not (:closed? async-resp)))
|
(is (not (:closed? async-resp)))
|
||||||
(is (contains-all-of? (:headers async-resp)
|
(is (contains-all-of?
|
||||||
(dissoc (:headers options) "Content-Type")))
|
(:headers async-resp)
|
||||||
|
(dissoc (:headers default-options) "Content-Type")))
|
||||||
; 5. verify data was sent
|
; 5. verify data was sent
|
||||||
(is (= (get-edn-from-arrays arrays 0)
|
(is (= (get-edn-from-arrays arrays 0)
|
||||||
{:foo "bar"}))))))
|
{:foo "bar"}))))))
|
||||||
|
|
||||||
(deftest send-data-to-client-after-backchannel-reconnect
|
(deftest send-data-to-client-after-backchannel-reconnect
|
||||||
(let [options default-options
|
(let [; 1. forwardchannel request to create session
|
||||||
; 1. forwardchannel request to create session
|
create-resp (app (->new-session-request))
|
||||||
create-resp (app (->new-session-request) options)
|
|
||||||
session-id (get-session-id create-resp)
|
session-id (get-session-id create-resp)
|
||||||
; 2. backchannel request (long request, async response)
|
; 2. backchannel request (long request, async response)
|
||||||
back-resp (app (->new-backchannel-request session-id))]
|
back-resp (app (->new-backchannel-request session-id))]
|
||||||
|
@ -272,10 +270,10 @@
|
||||||
(let [options (-> default-options
|
(let [options (-> default-options
|
||||||
(assoc :keep-alive-interval 2))
|
(assoc :keep-alive-interval 2))
|
||||||
; 1. forwardchannel request to create session
|
; 1. forwardchannel request to create session
|
||||||
create-resp (app (->new-session-request) options)
|
create-resp (app (->new-session-request) :options options)
|
||||||
session-id (get-session-id create-resp)
|
session-id (get-session-id create-resp)
|
||||||
; 2. backchannel request (long request, async response)
|
; 2. backchannel request (long request, async response)
|
||||||
back-resp (app (->new-backchannel-request session-id))]
|
back-resp (app (->new-backchannel-request session-id) :options options)]
|
||||||
(wait-for-agent-send-offs)
|
(wait-for-agent-send-offs)
|
||||||
(is (:heartbeat-timeout @(get @sessions session-id)))
|
(is (:heartbeat-timeout @(get @sessions session-id)))
|
||||||
; 3. wait for heartbeat/keepalive interval to elapse
|
; 3. wait for heartbeat/keepalive interval to elapse
|
||||||
|
@ -286,8 +284,9 @@
|
||||||
(is (= 200 (:status back-resp)))
|
(is (= 200 (:status back-resp)))
|
||||||
(is (= 200 (:status async-resp)))
|
(is (= 200 (:status async-resp)))
|
||||||
(is (not (:closed? async-resp)))
|
(is (not (:closed? async-resp)))
|
||||||
(is (contains-all-of? (:headers async-resp)
|
(is (contains-all-of?
|
||||||
(dissoc (:headers options) "Content-Type")))
|
(:headers async-resp)
|
||||||
|
(dissoc (:headers options) "Content-Type")))
|
||||||
; 5. verify data was sent ("noop" is the standard keepalive message that is sent)
|
; 5. verify data was sent ("noop" is the standard keepalive message that is sent)
|
||||||
(is (= (get-raw-from-arrays arrays 0)
|
(is (= (get-raw-from-arrays arrays 0)
|
||||||
["noop"])))))
|
["noop"])))))
|
||||||
|
@ -296,7 +295,7 @@
|
||||||
(let [options (-> default-options
|
(let [options (-> default-options
|
||||||
(assoc :keep-alive-interval 2))
|
(assoc :keep-alive-interval 2))
|
||||||
; 1. forwardchannel request to create session
|
; 1. forwardchannel request to create session
|
||||||
create-resp (app (->new-session-request) options)
|
create-resp (app (->new-session-request) :options options)
|
||||||
session-id (get-session-id create-resp)]
|
session-id (get-session-id create-resp)]
|
||||||
(wait-for-agent-send-offs)
|
(wait-for-agent-send-offs)
|
||||||
(is (connected? session-id))
|
(is (connected? session-id))
|
||||||
|
@ -311,10 +310,10 @@
|
||||||
(let [options (-> default-options
|
(let [options (-> default-options
|
||||||
(assoc :keep-alive-interval 2))
|
(assoc :keep-alive-interval 2))
|
||||||
; 1. forwardchannel request to create session
|
; 1. forwardchannel request to create session
|
||||||
create-resp (app (->new-session-request) options)
|
create-resp (app (->new-session-request) :options options)
|
||||||
session-id (get-session-id create-resp)
|
session-id (get-session-id create-resp)
|
||||||
; 2. backchannel request (long request, async response)
|
; 2. backchannel request (long request, async response)
|
||||||
back-resp (app (->new-backchannel-request session-id))]
|
back-resp (app (->new-backchannel-request session-id) :options options)]
|
||||||
(wait-for-agent-send-offs)
|
(wait-for-agent-send-offs)
|
||||||
(is (:heartbeat-timeout @(get @sessions session-id)))
|
(is (:heartbeat-timeout @(get @sessions session-id)))
|
||||||
; 3. close backchannel. we do it via clear-back-channel directly as it better
|
; 3. close backchannel. we do it via clear-back-channel directly as it better
|
||||||
|
@ -331,7 +330,7 @@
|
||||||
; reset async response output. hacky necessity due to the way we capture this output
|
; reset async response output. hacky necessity due to the way we capture this output
|
||||||
(reset! async-output {})
|
(reset! async-output {})
|
||||||
; 5. second backchannel request
|
; 5. second backchannel request
|
||||||
(let [back-resp (app (->new-backchannel-request session-id))]
|
(let [back-resp (app (->new-backchannel-request session-id) :options options)]
|
||||||
(wait-for-agent-send-offs)
|
(wait-for-agent-send-offs)
|
||||||
(is (:heartbeat-timeout @(get @sessions session-id)))
|
(is (:heartbeat-timeout @(get @sessions session-id)))
|
||||||
; 6. wait for heartbeat/keepalive interval to elapse
|
; 6. wait for heartbeat/keepalive interval to elapse
|
||||||
|
@ -350,7 +349,7 @@
|
||||||
(let [options (-> default-options
|
(let [options (-> default-options
|
||||||
(assoc :session-timeout-interval 3))
|
(assoc :session-timeout-interval 3))
|
||||||
; 1. forwardchannel request to create session
|
; 1. forwardchannel request to create session
|
||||||
create-resp (app (->new-session-request) options)
|
create-resp (app (->new-session-request) :options options)
|
||||||
session-id (get-session-id create-resp)]
|
session-id (get-session-id create-resp)]
|
||||||
(wait-for-agent-send-offs)
|
(wait-for-agent-send-offs)
|
||||||
(is (connected? session-id))
|
(is (connected? session-id))
|
||||||
|
@ -364,10 +363,10 @@
|
||||||
(let [options (-> default-options
|
(let [options (-> default-options
|
||||||
(assoc :session-timeout-interval 3))
|
(assoc :session-timeout-interval 3))
|
||||||
; 1. forwardchannel request to create session
|
; 1. forwardchannel request to create session
|
||||||
create-resp (app (->new-session-request) options)
|
create-resp (app (->new-session-request) :options options)
|
||||||
session-id (get-session-id create-resp)
|
session-id (get-session-id create-resp)
|
||||||
; 2. backchannel request (long request, async response)
|
; 2. backchannel request (long request, async response)
|
||||||
back-resp (app (->new-backchannel-request session-id))]
|
back-resp (app (->new-backchannel-request session-id) :options options)]
|
||||||
(wait-for-agent-send-offs)
|
(wait-for-agent-send-offs)
|
||||||
(is (connected? session-id))
|
(is (connected? session-id))
|
||||||
(is (not (:session-timeout @(get @sessions session-id))))
|
(is (not (:session-timeout @(get @sessions session-id))))
|
||||||
|
@ -379,9 +378,8 @@
|
||||||
(is (not (:session-timeout @(get @sessions session-id))))))
|
(is (not (:session-timeout @(get @sessions session-id))))))
|
||||||
|
|
||||||
(deftest session-timeout-is-reactivated-after-backchannel-close-test
|
(deftest session-timeout-is-reactivated-after-backchannel-close-test
|
||||||
(let [options default-options
|
(let [; 1. forwardchannel request to create session
|
||||||
; 1. forwardchannel request to create session
|
create-resp (app (->new-session-request))
|
||||||
create-resp (app (->new-session-request) options)
|
|
||||||
session-id (get-session-id create-resp)
|
session-id (get-session-id create-resp)
|
||||||
; 2. backchannel request (long request, async response)
|
; 2. backchannel request (long request, async response)
|
||||||
back-resp (app (->new-backchannel-request session-id))]
|
back-resp (app (->new-backchannel-request session-id))]
|
||||||
|
@ -406,14 +404,13 @@
|
||||||
(swap! event-output assoc :on-close {:session-id session-id
|
(swap! event-output assoc :on-close {:session-id session-id
|
||||||
:request request
|
:request request
|
||||||
:reason reason}))
|
:reason reason}))
|
||||||
options (-> default-options
|
events {:on-open on-open
|
||||||
(assoc :events {:on-open on-open
|
:on-close on-close}
|
||||||
:on-close on-close}))
|
|
||||||
; 1. forwardchannel request to create session
|
; 1. forwardchannel request to create session
|
||||||
create-resp (app (->new-session-request) options)
|
create-resp (app (->new-session-request) :events events)
|
||||||
session-id (get-session-id create-resp)
|
session-id (get-session-id create-resp)
|
||||||
; 2. backchannel request (long request, async response)
|
; 2. backchannel request (long request, async response)
|
||||||
back-resp (app (->new-backchannel-request session-id))]
|
back-resp (app (->new-backchannel-request session-id) :events events)]
|
||||||
(wait-for-agent-send-offs)
|
(wait-for-agent-send-offs)
|
||||||
; 3. verify that on-open event was fired and was passed correct arguments
|
; 3. verify that on-open event was fired and was passed correct arguments
|
||||||
; (see on-open function defined above)
|
; (see on-open function defined above)
|
||||||
|
@ -441,13 +438,12 @@
|
||||||
(swap! received conj {:session-id session-id
|
(swap! received conj {:session-id session-id
|
||||||
:request request
|
:request request
|
||||||
:data data}))
|
:data data}))
|
||||||
options (-> default-options
|
events {:on-receive on-receive}
|
||||||
(assoc :events {:on-receive on-receive}))
|
|
||||||
; 1. forwardchannel request to create session
|
; 1. forwardchannel request to create session
|
||||||
create-resp (app (->new-session-request) options)
|
create-resp (app (->new-session-request) :events events)
|
||||||
session-id (get-session-id create-resp)
|
session-id (get-session-id create-resp)
|
||||||
; 2. backchannel request (long request, async response)
|
; 2. backchannel request (long request, async response)
|
||||||
back-resp (app (->new-backchannel-request session-id))]
|
back-resp (app (->new-backchannel-request session-id) :events events)]
|
||||||
(wait-for-agent-send-offs)
|
(wait-for-agent-send-offs)
|
||||||
; 3. forwardchannel request so simulate sending data from client to server
|
; 3. forwardchannel request so simulate sending data from client to server
|
||||||
(let [forward-resp (app (-> (mock/request
|
(let [forward-resp (app (-> (mock/request
|
||||||
|
@ -463,7 +459,8 @@
|
||||||
(mock/body
|
(mock/body
|
||||||
{"count" "1"
|
{"count" "1"
|
||||||
"ofs" "0"
|
"ofs" "0"
|
||||||
"req0___edn" (pr-str {:foo "bar"})})))
|
"req0___edn" (pr-str {:foo "bar"})}))
|
||||||
|
:events events)
|
||||||
; 4. parse response body
|
; 4. parse response body
|
||||||
[len status] (string/split (:body forward-resp) #"\n" 2)
|
[len status] (string/split (:body forward-resp) #"\n" 2)
|
||||||
[backchannel-present last-bkch-array-id outstanding-bytes] (json/parse-string status)]
|
[backchannel-present last-bkch-array-id outstanding-bytes] (json/parse-string status)]
|
||||||
|
@ -491,13 +488,12 @@
|
||||||
(swap! received conj {:session-id session-id
|
(swap! received conj {:session-id session-id
|
||||||
:request request
|
:request request
|
||||||
:data data}))
|
:data data}))
|
||||||
options (-> default-options
|
events {:on-receive on-receive}
|
||||||
(assoc :events {:on-receive on-receive}))
|
|
||||||
; 1. forwardchannel request to create session
|
; 1. forwardchannel request to create session
|
||||||
create-resp (app (->new-session-request) options)
|
create-resp (app (->new-session-request) :events events)
|
||||||
session-id (get-session-id create-resp)
|
session-id (get-session-id create-resp)
|
||||||
; 2. backchannel request (long request, async response)
|
; 2. backchannel request (long request, async response)
|
||||||
back-resp (app (->new-backchannel-request session-id))]
|
back-resp (app (->new-backchannel-request session-id) :events events)]
|
||||||
(wait-for-agent-send-offs)
|
(wait-for-agent-send-offs)
|
||||||
; 3. forwardchannel request so simulate sending data from client to server
|
; 3. forwardchannel request so simulate sending data from client to server
|
||||||
; (2 maps included)
|
; (2 maps included)
|
||||||
|
@ -515,7 +511,8 @@
|
||||||
{"count" "2"
|
{"count" "2"
|
||||||
"ofs" "0"
|
"ofs" "0"
|
||||||
"req0___edn" (pr-str {:foo "bar"})
|
"req0___edn" (pr-str {:foo "bar"})
|
||||||
"req1___edn" (pr-str {:second "map"})})))
|
"req1___edn" (pr-str {:second "map"})}))
|
||||||
|
:events events)
|
||||||
; 4. parse response body
|
; 4. parse response body
|
||||||
[len status] (string/split (:body forward-resp) #"\n" 2)
|
[len status] (string/split (:body forward-resp) #"\n" 2)
|
||||||
[backchannel-present last-bkch-array-id outstanding-bytes] (json/parse-string status)]
|
[backchannel-present last-bkch-array-id outstanding-bytes] (json/parse-string status)]
|
||||||
|
@ -577,20 +574,19 @@
|
||||||
(let [received (atom [])
|
(let [received (atom [])
|
||||||
on-receive (fn [session-id request data]
|
on-receive (fn [session-id request data]
|
||||||
(swap! received conj data))
|
(swap! received conj data))
|
||||||
options (-> default-options
|
events {:on-receive on-receive}
|
||||||
(assoc :events {:on-receive on-receive}))
|
|
||||||
; 1. forwardchannel request to create session
|
; 1. forwardchannel request to create session
|
||||||
create-resp (app (->new-session-request) options)
|
create-resp (app (->new-session-request) :events events)
|
||||||
session-id (get-session-id create-resp)
|
session-id (get-session-id create-resp)
|
||||||
; 2. backchannel request (long request, async response)
|
; 2. backchannel request (long request, async response)
|
||||||
back-resp (app (->new-backchannel-request session-id))]
|
back-resp (app (->new-backchannel-request session-id) :events events)]
|
||||||
(wait-for-agent-send-offs)
|
(wait-for-agent-send-offs)
|
||||||
; 3. forwardchannel request to send data from client to server
|
; 3. forwardchannel request to send data from client to server
|
||||||
(let [forward-resp (app (->new-forwardchannel-request session-id 0 "hello 1"))
|
(let [forward-resp (app (->new-forwardchannel-request session-id 0 "hello 1") :events events)
|
||||||
result1 (parse-forward-response forward-resp)]
|
result1 (parse-forward-response forward-resp)]
|
||||||
(wait-for-agent-send-offs)
|
(wait-for-agent-send-offs)
|
||||||
; 4. a second forwardchannel request to send more data from client to server
|
; 4. a second forwardchannel request to send more data from client to server
|
||||||
(let [forward2-resp (app (->new-forwardchannel-request session-id 0 "hello 2"))
|
(let [forward2-resp (app (->new-forwardchannel-request session-id 0 "hello 2") :events events)
|
||||||
result2 (parse-forward-response forward2-resp)]
|
result2 (parse-forward-response forward2-resp)]
|
||||||
(wait-for-agent-send-offs)
|
(wait-for-agent-send-offs)
|
||||||
(is (= 0 (:last-bkch-array-id result1)))
|
(is (= 0 (:last-bkch-array-id result1)))
|
||||||
|
@ -609,14 +605,13 @@
|
||||||
(let [received (atom [])
|
(let [received (atom [])
|
||||||
on-receive (fn [session-id request data]
|
on-receive (fn [session-id request data]
|
||||||
(swap! received conj data))
|
(swap! received conj data))
|
||||||
options (-> default-options
|
events {:on-receive on-receive}
|
||||||
(assoc :events {:on-receive on-receive}))
|
|
||||||
; 1. forwardchannel request to create session
|
; 1. forwardchannel request to create session
|
||||||
create-resp (app (->new-session-request) options)
|
create-resp (app (->new-session-request) :events events)
|
||||||
session-id (get-session-id create-resp)]
|
session-id (get-session-id create-resp)]
|
||||||
(wait-for-agent-send-offs)
|
(wait-for-agent-send-offs)
|
||||||
; 2. forwardchannel request to send data from client to server
|
; 2. forwardchannel request to send data from client to server
|
||||||
(let [forward-resp (app (->new-forwardchannel-request session-id 0 :foobar))
|
(let [forward-resp (app (->new-forwardchannel-request session-id 0 :foobar) :events events)
|
||||||
result (parse-forward-response forward-resp)]
|
result (parse-forward-response forward-resp)]
|
||||||
(wait-for-agent-send-offs)
|
(wait-for-agent-send-offs)
|
||||||
(is (= 0 (:backchannel-present result)))
|
(is (= 0 (:backchannel-present result)))
|
||||||
|
@ -635,8 +630,7 @@
|
||||||
(swap! received conj {:session-id session-id
|
(swap! received conj {:session-id session-id
|
||||||
:request request
|
:request request
|
||||||
:data data}))
|
:data data}))
|
||||||
options (-> default-options
|
events {:on-receive on-receive}
|
||||||
(assoc :events {:on-receive on-receive}))
|
|
||||||
; 1. forwardchannel request to create session. encode a map to be sent as part
|
; 1. forwardchannel request to create session. encode a map to be sent as part
|
||||||
; of this request (encoded in same format as any other forwardchannel request
|
; of this request (encoded in same format as any other forwardchannel request
|
||||||
; would do to send client->server data)
|
; would do to send client->server data)
|
||||||
|
@ -652,7 +646,7 @@
|
||||||
{"count" "1"
|
{"count" "1"
|
||||||
"ofs" "0"
|
"ofs" "0"
|
||||||
"req0___edn" (pr-str {:msg "hello, world"})}))
|
"req0___edn" (pr-str {:msg "hello, world"})}))
|
||||||
options)
|
:events events)
|
||||||
session-id (get-session-id create-resp)]
|
session-id (get-session-id create-resp)]
|
||||||
(wait-for-agent-send-offs)
|
(wait-for-agent-send-offs)
|
||||||
(is (connected? session-id))
|
(is (connected? session-id))
|
||||||
|
@ -668,10 +662,9 @@
|
||||||
(let [received (atom [])
|
(let [received (atom [])
|
||||||
on-receive (fn [session-id request data]
|
on-receive (fn [session-id request data]
|
||||||
(swap! received conj data))
|
(swap! received conj data))
|
||||||
options (-> default-options
|
events {:on-receive on-receive}
|
||||||
(assoc :events {:on-receive on-receive}))
|
|
||||||
; 1. forwardchannel request to create session
|
; 1. forwardchannel request to create session
|
||||||
create-resp (app (->new-session-request) options)
|
create-resp (app (->new-session-request) :events events)
|
||||||
session-id (get-session-id create-resp)
|
session-id (get-session-id create-resp)
|
||||||
str-to-send "this will get queued but not sent because no backchannel is open"
|
str-to-send "this will get queued but not sent because no backchannel is open"
|
||||||
queued-str (pr-str (encode-map str-to-send))]
|
queued-str (pr-str (encode-map str-to-send))]
|
||||||
|
@ -680,7 +673,7 @@
|
||||||
(send-data session-id str-to-send)
|
(send-data session-id str-to-send)
|
||||||
(wait-for-agent-send-offs)
|
(wait-for-agent-send-offs)
|
||||||
; 3. forwardchannel request to send data from client to server
|
; 3. forwardchannel request to send data from client to server
|
||||||
(let [forward-resp (app (->new-forwardchannel-request session-id 0 42))
|
(let [forward-resp (app (->new-forwardchannel-request session-id 0 42) :events events)
|
||||||
result (parse-forward-response forward-resp)]
|
result (parse-forward-response forward-resp)]
|
||||||
(wait-for-agent-send-offs)
|
(wait-for-agent-send-offs)
|
||||||
; 4. verify that the response to the forwardchannel request contained correct backchannel
|
; 4. verify that the response to the forwardchannel request contained correct backchannel
|
||||||
|
@ -707,7 +700,7 @@
|
||||||
options (-> default-options
|
options (-> default-options
|
||||||
(assoc :fail-fn fail-fn))
|
(assoc :fail-fn fail-fn))
|
||||||
; 2. forwardchannel request to create session
|
; 2. forwardchannel request to create session
|
||||||
create-resp (app (->new-session-request) options)
|
create-resp (app (->new-session-request) :options options)
|
||||||
session-id (get-session-id create-resp)]
|
session-id (get-session-id create-resp)]
|
||||||
(wait-for-agent-send-offs)
|
(wait-for-agent-send-offs)
|
||||||
; 3. queue up a bunch of data to be sent. no backchannel has been created yet,
|
; 3. queue up a bunch of data to be sent. no backchannel has been created yet,
|
||||||
|
@ -718,7 +711,7 @@
|
||||||
(send-data session-id "fail")
|
(send-data session-id "fail")
|
||||||
(send-data session-id :fourth-queued)
|
(send-data session-id :fourth-queued)
|
||||||
; 4. backchannel request (long request, async response)
|
; 4. backchannel request (long request, async response)
|
||||||
(let [back-resp (app (->new-backchannel-request session-id) options)]
|
(let [back-resp (app (->new-backchannel-request session-id) :options options)]
|
||||||
(wait-for-agent-send-offs)
|
(wait-for-agent-send-offs)
|
||||||
; 5. an exception should have been thrown during the flush-buffer call, but
|
; 5. an exception should have been thrown during the flush-buffer call, but
|
||||||
; we should have sent out some of the data before then
|
; we should have sent out some of the data before then
|
||||||
|
@ -735,7 +728,7 @@
|
||||||
(reset! async-output {})
|
(reset! async-output {})
|
||||||
; 7. re-open backchannel. all 4 items should still be in the buffer and will
|
; 7. re-open backchannel. all 4 items should still be in the buffer and will
|
||||||
; get flushed again at this point
|
; get flushed again at this point
|
||||||
(let [back-resp (app (->new-backchannel-request session-id) options)]
|
(let [back-resp (app (->new-backchannel-request session-id) :options options)]
|
||||||
(wait-for-agent-send-offs)
|
(wait-for-agent-send-offs)
|
||||||
; 8. at this point, all 4 items should have been sent and the backchannel request
|
; 8. at this point, all 4 items should have been sent and the backchannel request
|
||||||
; should still be active
|
; should still be active
|
||||||
|
|
|
@ -12,13 +12,13 @@
|
||||||
(use-fixtures :each async-output-fixture)
|
(use-fixtures :each async-output-fixture)
|
||||||
|
|
||||||
(defn app
|
(defn app
|
||||||
[request & [options]]
|
[request & {:keys [events options]}]
|
||||||
((-> (fn [{:keys [uri] :as request}]
|
((-> (fn [{:keys [uri] :as request}]
|
||||||
(if (or (= "" uri)
|
(if (or (= "" uri)
|
||||||
(= "/" uri))
|
(= "/" uri))
|
||||||
(response/response "Hello, world!")
|
(response/response "Hello, world!")
|
||||||
(response/not-found "not found")))
|
(response/not-found "not found")))
|
||||||
(wrap-browserchannel (or options default-options))
|
(wrap-browserchannel events (or options default-options))
|
||||||
(wrap-test-async-adapter (or options default-options)))
|
(wrap-test-async-adapter (or options default-options)))
|
||||||
request))
|
request))
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@
|
||||||
"MODE" "init"
|
"MODE" "init"
|
||||||
"zx" (random-string)
|
"zx" (random-string)
|
||||||
"t" 1})
|
"t" 1})
|
||||||
options)
|
:options options)
|
||||||
body (json/parse-string (:body resp))]
|
body (json/parse-string (:body resp))]
|
||||||
(is (= 200 (:status resp)))
|
(is (= 200 (:status resp)))
|
||||||
(is (contains-all-of? (:headers resp) (:headers default-options)))
|
(is (contains-all-of? (:headers resp) (:headers default-options)))
|
||||||
|
|
Reference in a new issue