From 145ecc5ddb2ba8f4c2fc94268da11e756a5fdd3b Mon Sep 17 00:00:00 2001 From: gered Date: Thu, 19 May 2016 17:06:57 -0400 Subject: [PATCH] add browserchannel messaging backend library --- reagent-data-views-browserchannel/project.clj | 16 +++++++++ .../browserchannel/client.cljs | 33 +++++++++++++++++++ .../browserchannel/server.clj | 31 +++++++++++++++++ .../src/reagent_data_views/client/core.cljs | 10 ++++++ 4 files changed, 90 insertions(+) create mode 100644 reagent-data-views-browserchannel/project.clj create mode 100644 reagent-data-views-browserchannel/src/reagent_data_views/browserchannel/client.cljs create mode 100644 reagent-data-views-browserchannel/src/reagent_data_views/browserchannel/server.clj diff --git a/reagent-data-views-browserchannel/project.clj b/reagent-data-views-browserchannel/project.clj new file mode 100644 index 0000000..a6bd640 --- /dev/null +++ b/reagent-data-views-browserchannel/project.clj @@ -0,0 +1,16 @@ +(defproject reagent-data-views-browserchannel "0.1.0-SNAPSHOT" + :description "BrowserChannel client/server support for reagent-data-views." + :url "https://github.com/gered/reagent-data-views" + :license {:name "MIT License" + :url "http://opensource.org/licenses/MIT"} + + :dependencies [[org.clojure/clojure "1.8.0"]] + + :profiles {:provided + {:dependencies + [[org.clojure/clojure "1.8.0"] + [org.clojure/clojurescript "1.8.51"] + [reagent "0.6.0-alpha"] + [gered/views "1.5-SNAPSHOT"] + [reagent-data-views "0.2.0-SNAPSHOT"] + [gered/clj-browserchannel "0.3.1"]]}}) diff --git a/reagent-data-views-browserchannel/src/reagent_data_views/browserchannel/client.cljs b/reagent-data-views-browserchannel/src/reagent_data_views/browserchannel/client.cljs new file mode 100644 index 0000000..c551e98 --- /dev/null +++ b/reagent-data-views-browserchannel/src/reagent_data_views/browserchannel/client.cljs @@ -0,0 +1,33 @@ +(ns reagent-data-views.browserchannel.client + (:require + [net.thegeez.browserchannel.client :as browserchannel] + [reagent-data-views.client.core :as client])) + +(defn configure! + "performs initial configuration necessary to hook browserchannel into reagent-data-views + as the client/server messaging backend. should be called once on page load before + browserchannel is initialized." + [] + (swap! client/send-fn + (fn [data] + (browserchannel/send-data! data)))) + +(def middleware + "clj-browserchannel client-side event middleware. this should be included in the + middleware list provided to net.thegeez.browserchannel.client/connect!" + {:on-receive + (fn [handler] + (fn [data] + (if-not (client/on-receive! data) + ; only pass along receive events for data not intended for the views system + (handler data)))) + + :on-opening + (fn [handler] + (fn [] + ; we do this in on-opening instead of on-open since with browserchannel we + ; have the ability to queue up messages to be sent to the server in the initial + ; connection request. if this connection is actually a reconnection, then any + ; subscription requests that need to be resent get sent all in one go this way. + (client/on-open!) + (handler)))}) diff --git a/reagent-data-views-browserchannel/src/reagent_data_views/browserchannel/server.clj b/reagent-data-views-browserchannel/src/reagent_data_views/browserchannel/server.clj new file mode 100644 index 0000000..1c6ece4 --- /dev/null +++ b/reagent-data-views-browserchannel/src/reagent_data_views/browserchannel/server.clj @@ -0,0 +1,31 @@ +(ns reagent-data-views.browserchannel.server + (:require + [clojure.tools.logging :as log] + [net.thegeez.browserchannel.server :as browserchannel] + [views.core :as views] + [reagent-data-views.server.core :as server])) + +(defn configure-views! + "performs browserchannel-specific initialization on the views system that is + necessary to hook views and reagent-data-views together via browserchannel." + [] + (views/set-send-fn! + (fn [client-id [[view-id parameters] view-data]] + (log/trace client-id "refresh view" [view-id parameters]) + (browserchannel/send-data! client-id [:views/refresh [view-id parameters] view-data])))) + +(def middleware + "clj-browserchannel server-side event middleware. this should be included in the + middleware list provided to wrap-browserchannel." + {:on-receive + (fn [handler] + (fn [client-id request data] + (if-not (server/on-receive! client-id data) + ; only pass along receive events for data not intended for the views system + (handler client-id request data)))) + + :on-close + (fn [handler] + (fn [client-id request reason] + (server/on-close! client-id) + (handler client-id request reason)))}) diff --git a/reagent-data-views/src/reagent_data_views/client/core.cljs b/reagent-data-views/src/reagent_data_views/client/core.cljs index ceab133..9a74338 100644 --- a/reagent-data-views/src/reagent_data_views/client/core.cljs +++ b/reagent-data-views/src/reagent_data_views/client/core.cljs @@ -89,6 +89,16 @@ (unsubscribe! old-view-sigs) (subscribe! new-view-sigs)) +(defn on-open! + [] + (if (seq @view-data) + ; if there are existing subscriptions right when the messaging system connects + ; to the server, then it means that this was probably a reconnection. + ; the server removes subscriptions when a client disconnects, so we should + ; send subscriptions for all of the views that were left in view-data + (doseq [view-sig (keys @view-data)] + (send-data! [:views/subscribe view-sig])))) + (defn on-receive! [data] (when (relevant-event? data)