2015-08-07 8 views
1

Я следующий код сервера:Как использовать сервер http.kit с обработчиком рингбринга?

(ns tweet-sentiment.server 
(:require [clojure.java.io :as io] 
      [tweet-sentiment.dev :refer [is-dev? inject-devmode-html browser-repl start-figwheel start-less]] 
      [compojure.core :refer [GET POST defroutes]] 
      [compojure.route :refer [resources]] 
      [net.cgrand.enlive-html :refer [deftemplate]] 
      [net.cgrand.reload :refer [auto-reload]] 
      [ring.middleware.reload :as reload] 
      [ring.middleware.defaults :refer [wrap-defaults api-defaults]] 
      [tweet-sentiment.utils :refer [generate-response]] 
      [environ.core :refer [env]] 
      [org.httpkit.server :refer [run-server]] 
      [ring.middleware.edn :refer [wrap-edn-params]] 
      [tweet-sentiment.tweets :refer [tweets]] 
      [tweet-sentiment.dandelion :refer [dandelion-sentiment]] 
      [clojure.core.async :refer [>!! <!! put! take! pipe chan]] 
      [cemerick.drawbridge :as drawbridge] 
      [ring.middleware.basic-authentication :refer [wrap-basic-authentication]] 
      ) 
    (:gen-class)) 

(defonce server (atom nil)) 

(deftemplate page (io/resource "index.html") [] 
      [:body] (if is-dev? inject-devmode-html identity)) 

(defroutes routes 
      (resources "/") 
      (resources "/react" {:root "react"}) 
      (GET "/*" req (page))) 


(defn wrap-drawbridge [handler] 
    (fn [req] 
    (if (= "/repl" (:uri req)) 
     (drawbridge/ring-handler req) 
     (handler req)))) 

(def http-handler 
    (if is-dev? 
    (-> #'routes 
     (wrap-defaults api-defaults) 
     reload/wrap-reload 
     wrap-edn-params 
     wrap-drawbridge) 

    (-> (wrap-defaults #'routes api-defaults) 
     wrap-edn-params 
     wrap-drawbridge))) 

(defn run-web-server [& [port]] 
    (let [port (Integer. (or port (env :port) 10555))] 
    (println (format "Starting web server on port %d." port)) 
    (reset! server (run-server http-handler {:port port :join? false})))) 

(defn run-auto-reload [& [port]] 
    (auto-reload *ns*) 
    (start-figwheel) 
    (start-less)) 

(defn run [& [port]] 
    (when is-dev? 
    (run-auto-reload)) 
    (run-web-server port)) 

(defn stop-server [] 
    (when-not (nil? @server) 
    (@server :timeout 0) 
    (reset! server nil))) 

(defn restart-server [] 
    (stop-server) 
    (run-web-server)) 

(defn -main [& [port]] 
    (run port)) 

При попытке подключиться к подъемному мосту REPL, как разработчика или производства:

lein repl :connect http://localhost:10555/repl

Я получаю следующее сообщение об ошибке:

ERROR - POST /repl 
java.lang.IllegalArgumentException: No value supplied for key: {:remote-addr "127.0.0.1", :headers {"accept-encoding" "gzip, deflate", "connection" "close", "content-length" "48", "content-type" "application/x-www-form-urlencoded", "host" "localhost:10555", "user-agent" "Apache-HttpClient/4.3.3 (java 1.5)"}, :async-channel #<AsyncChannel /127.0.0.1:10555<->/127.0.0.1:60374>, :server-port 10555, :content-length 48, :websocket? false, :content-type "application/x-www-form-urlencoded", :character-encoding "utf8", :uri "/repl", :server-name "localhost", :query-string nil, :body #<BytesInputStream BytesInputStream[len=48]>, :scheme :http, :request-method :post} 
    at clojure.lang.PersistentHashMap.create(PersistentHashMap.java:77) 
    at cemerick.drawbridge$ring_handler.doInvoke(drawbridge.clj:49) 
    at clojure.lang.RestFn.invoke(RestFn.java:408) 
    at tweet_sentiment.server$wrap_drawbridge$fn__21884.invoke(server.clj:36) 
    at org.httpkit.server.HttpHandler.run(RingHandler.java:91) 
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at java.lang.Thread.run(Thread.java:745) 

задачи очевидно, находится в функции drawbridge/ring-handler. Это моя зависимость:

[[org.clojure/clojure "1.6.0"] 
       [org.clojure/clojurescript "0.0-3058" :scope "provided"] 
       [ring "1.3.2"] 
       [ring/ring-defaults "0.1.4"] 
       [compojure "1.3.2"] 
       [enlive "1.1.6"] 
       [org.omcljs/om "0.8.8"] 
       [om-sync "0.1.1"] 
       [environ "1.0.0"] 
       [http-kit "2.1.19"] 
       [fogus/ring-edn "0.3.0"] 
       [prismatic/om-tools "0.3.11"] 
       [secretary "1.2.3"] 
       [sablono "0.3.4"] 
       [twitter-api "0.7.8"] 
       [racehub/om-bootstrap "0.5.3"] 
       [cheshire "5.2.0"] 
       [com.cemerick/drawbridge "0.0.7"] 
       [ring-basic-authentication "1.0.1"]] 

ли кто-нибудь получить работающий сервер http.kit с drawbrige? Что мне не хватает?

ответ

1

В конце концов я понял это, файловый сервер должен выглядеть примерно так

(ns tweet-sentiment.server 
    (:require [clojure.java.io :as io] 
      [tweet-sentiment.dev :refer [is-dev? inject-devmode-html browser-repl start-figwheel start-less]] 
      [compojure.core :refer [GET POST defroutes]] 
      [compojure.route :refer [resources]] 
      [net.cgrand.enlive-html :refer [deftemplate]] 
      [net.cgrand.reload :refer [auto-reload]] 
      [ring.middleware.reload :as reload] 
      [ring.middleware.defaults :refer [wrap-defaults api-defaults]] 
      [tweet-sentiment.utils :refer [generate-response]] 
      [environ.core :refer [env]] 
      [org.httpkit.server :refer [run-server]] 
      [ring.middleware.edn :refer [wrap-edn-params]] 
      [clojure.core.async :refer [>!! <!! put! take! pipe chan]] 
      [cemerick.drawbridge :as drawbridge] 
      [ring.middleware.basic-authentication :refer [wrap-basic-authentication]] 
      [ring.middleware.params :as params] 
      [ring.middleware.keyword-params :as keyword-params] 
      [ring.middleware.nested-params :as nested-params] 
      [ring.middleware.session :as session] 
      ) 
    (:gen-class)) 

(defonce server (atom nil)) 

(deftemplate page (io/resource "index.html") [] 
      [:body] (if is-dev? inject-devmode-html identity)) 

(defroutes routes 
      (resources "/") 
      (resources "/react" {:root "react"}) 
      (GET "/*" req (page))) 

(defn authenticated? [name pass] 
    (= [name pass] [(System/getenv "AUTH_USER") (System/getenv "AUTH_PASS")])) 

(def drawbridge-handler 
    (-> (drawbridge/ring-handler) 
     (keyword-params/wrap-keyword-params) 
     (nested-params/wrap-nested-params) 
     (params/wrap-params) 
     (session/wrap-session))) 

(defn http-handler [handler] 
    (-> handler 
     (wrap-defaults api-defaults) 
     wrap-edn-params)) 

(defn wrap-http [handler] 
    (fn [req] 
    (let [handler (if (= "/repl" (:uri req)) 
        (wrap-basic-authentication drawbridge-handler authenticated?) 
        (if is-dev? 
         (-> handler 
          http-handler 
          reload/wrap-reload) 
         (-> handler 
          http-handler)))] 
     (handler req)))) 

(defn run-web-server [& [port]] 
    (let [port (Integer. (or port (env :port) 10555))] 
    (println (format "Starting web server on port %d." port)) 
    (reset! server 
      (run-server (wrap-http #'routes) {:port port :join? false}) 
      ))) 

(defn run-auto-reload [& [port]] 
    (auto-reload *ns*) 
    (start-figwheel) 
    (start-less)) 

(defn run [& [port]] 
    (when is-dev? 
    (run-auto-reload)) 
    (run-web-server port)) 

(defn stop-server [] 
    (when-not (nil? @server) 
    (@server :timeout 0) 
    (reset! server nil))) 

(defn restart-server [] 
    (stop-server) 
    (run-web-server)) 

(defn -main [& [port]] 
    (run port)) 
+1

Этот вопрос и ответ был полезным, так как я мог изучить его и в конечном итоге найти свою ошибку, но, возможно, резюме также полезно. Что вам нужно сделать, это: - Возьми кольцо обработчик Подъемного моста и завернуть его в соответствующих обертках (см функции разводного-обработчик выше) - Положите его в итоговую основную аутентификацию - НЕ оберните его с большим количеством вещей, , Просто сделайте либо/или. Либо приложение, либо ответный чертеж. То есть сделайте wrap-drawbridge последним! Это сработало для меня. – AticusFinch