diff --git a/example-project/project.clj b/example-project/project.clj index 1095f55..198716a 100644 --- a/example-project/project.clj +++ b/example-project/project.clj @@ -23,6 +23,7 @@ ;;; ---> Choose (uncomment) a supported web server <--- [http-kit "2.1.19"] ;; [org.immutant/web "2.0.2"] + ;; [nginx-clojure/nginx-clojure-embed "0.4.2"] [ring "1.4.0"] [ring/ring-defaults "0.1.5"] ; Includes `ring-anti-forgery`, etc. diff --git a/example-project/src/example/my_app.cljx b/example-project/src/example/my_app.cljx index 9d8ea7f..1f4e8cd 100644 --- a/example-project/src/example/my_app.cljx +++ b/example-project/src/example/my_app.cljx @@ -43,6 +43,9 @@ ;; [immutant.web :as immutant] ;; [taoensso.sente.server-adapters.immutant :refer (sente-web-server-adapter)] + + ;; [nginx.clojure.embed :as nginx-clojure] + ;; [taoensso.sente.server-adapters.nginx-clojure :refer (sente-web-server-adapter)] ;; Optional, for Transit encoding: [taoensso.sente.packers.transit :as sente-transit]) @@ -86,6 +89,15 @@ ;; :port (:port server) ;; :stop-fn (fn [] (immutant/stop server))})) +;;; nginx-clojure embeded +;; #+clj +;; (defn start-web-server!* [ring-handler port] +;; (println "Starting nginx-clojure...") +;; (let [port (nginx-clojure/run-server ring-handler {:port port})] +;; {:server nil ; nginx-clojure doesn't expose this +;; :port port +;; :stop-fn nginx-clojure/stop-server})) + ;;;; Packer (client<->server serializtion format) config (def packer (sente-transit/get-flexi-packer :edn)) ; Experimental, needs Transit dep diff --git a/project.clj b/project.clj index deba5e9..585aed3 100644 --- a/project.clj +++ b/project.clj @@ -43,6 +43,7 @@ ;; [http-kit "2.1.19"] [org.immutant/web "2.0.0"] + [nginx-clojure "0.4.2"] ;; [lein-pprint "1.1.1"] [lein-ancient "0.6.7"] diff --git a/src/taoensso/sente/server_adapters/nginx_clojure.clj b/src/taoensso/sente/server_adapters/nginx_clojure.clj new file mode 100644 index 0000000..78f88ac --- /dev/null +++ b/src/taoensso/sente/server_adapters/nginx_clojure.clj @@ -0,0 +1,42 @@ +(ns taoensso.sente.server-adapters.nginx-clojure + "Experimental- subject to change! + Optional Nginx-Clojure v0.4.2+ adapter for use with Sente." + (:require [taoensso.sente.interfaces :as i] + [nginx.clojure.core :as ncc])) + +(def ^:dynamic *max-message-size* nginx.clojure.WholeMessageAdapter/DEFAULT_MAX_MESSAGE_SIZE) + +(extend-type nginx.clojure.NginxHttpServerChannel + i/IAsyncNetworkChannel + (open? [nc-ch] (not (ncc/closed? nc-ch))) + (close! [nc-ch] (ncc/close! nc-ch)) + (send!* [nc-ch msg close-after-send?] + (let [closed? (ncc/closed? nc-ch)] + (ncc/send! nc-ch msg true (boolean close-after-send?)) + (not closed?)))) + +(deftype NginxClojureAsyncNetworkChannelAdapter [] + i/IAsyncNetworkChannelAdapter + (ring-req->net-ch-resp [net-ch-adapter ring-req callbacks-map] + (let [{:keys [on-open on-msg on-close]} callbacks-map + nc-ch (ncc/hijack! ring-req true) + upgrade-ok? (ncc/websocket-upgrade! nc-ch false)] + ;; Returns {:status 200 :body }: + (when (not upgrade-ok?) ;; send general header for non-websocket request + (.setIgnoreFilter nc-ch false) + ;; Give a chance to set client broken listener. + ;; Generally it can be mereged with invoking send-header! + ;; e.g. (send-header! nc-ch 200, ..., true, false) + ;; We do not merge them here just to make its behavior be the same with + ;; those of other server adapters + (ncc/send! nc-ch nil true false) + (ncc/send-header! nc-ch 200 {"Content-Type" "text/html"} false false)) + (ncc/add-aggregated-listener! nc-ch *max-message-size* + {:on-open (when on-open (fn [nc-ch] (on-open nc-ch))) + :on-error nil ;;Do we need/want this? + :on-message (when on-msg (fn [nc-ch msg] (on-msg nc-ch msg))) + :on-close (when on-close (fn [nc-ch reason] (on-close nc-ch reason)))}) + {:status 200 :body nc-ch}))) + +(def nginx-clojure-adapter (NginxClojureAsyncNetworkChannelAdapter.)) +(def sente-web-server-adapter nginx-clojure-adapter) ; Alias for ns import convenience