4

我正在尝试研究如何让会话和闪存在 Google App Engine 中工作。有人可以使用环或沙洲提供一个明确的例子吗?我想我有沙洲工作,特别是它没有告诉我,Var sandbar.stateful-session/sandbar-flash is unbound当我转储处理程序时,我得到了:flash:session虽然我不确定那是沙洲会话还是环形会话。为了完整起见,我会提到我正在使用最新版本的 appengine-magic、ring、hiccup 和 sandbar。似乎没有任何不兼容或问题。

因此,最好使用flash-put!, flash-get, session-put! and session-get.

4

2 回答 2

4

我通常不喜欢回答自己的问题,但在这种情况下,我会例外,因为:

a) 那里没有很多容易理解的例子。

b) 有一个快速的工作示例供其他人使用会很好。

注意:这里不需要 appengine-magic,这也适用于正常的环会话

代码

;; Place in a file called session.clj in the example project
(ns example.session
    "Works with the normal ring sessions 
     allowing you to use side-effects to manage them")

(declare current-session)

(defn wrap-session! [handler]
  (fn [request]
    (binding [current-session (atom (or (:session request) {}))]
      (let [response (handler request)]
        (assoc response :session @current-session)))))

(defn session-get
  ([k] (session-get k nil))
  ([k default] (if (vector? k)
                 (get-in @current-session k)
                 (get @current-session k default))))

(defn session-put!
  ([m]
     (swap! current-session (fn [a b] (merge a m)) m))
  ([k v]
     (swap! current-session (fn [a b] (merge a {k b})) v)))

(defn session-pop! [k]
  (let [res (get @current-session k)]
    (swap! current-session (fn [a b] (dissoc a b)) k)
    res))

(defn session-delete-key! [k]
  (swap! current-session (fn [a b] (dissoc a b)) k))

(defn session-destroy! []
  (swap! current-session (constantly nil)))


;; Place in a file called core.clj in the example project
(ns example.core
  (:use compojure.core
        [ring.middleware.keyword-params :only [wrap-keyword-params]]
        [ring.middleware.session :only [wrap-session]]
        [ring.middleware.session.cookie :only [cookie-store]]
        [example session])
  (:require [appengine-magic.core :as ae]))

(declare current-session)

(defroutes example-app-routes
  (GET "/" _
       (fn [req]
         (let [counter (session-get :counter 0)]
           {:status 200
            :headers {"Content-Type" "text/plain"}
            :body (str "started: " counter)})))
  (GET "/inc" _
       (fn [req]
         (let [counter (do 
                        (session-put! :counter (inc (session-get :counter 0)))
                        (session-get :counter))]
           {:status 200
            :headers {"Content-Type" "text/plain"}
            :body (str "incremented: " counter)}))))

(def example-app-handler
  (-> #'example-app-routes
      wrap-keyword-params
      wrap-session!
      (wrap-session {:cookie-name "example-app-session"
                     :store (cookie-store)})))

(ae/def-appengine-app example-app #'example-app-handler)

如何使用它

导航到http://127.0.0.1:8080/inc会增加会话中的计数器, http: //127.0.0.1 :8080/将显示会话中计数器的值。

包装会议!会话不需要工作,只需使用

(wrap-session {:cookie-name "example-app-session"
                     :store (cookie-store)})

将为您提供工作功能会话。但是我想用副作用和包装会话来管理我的会话!提供该功能。要使用类似 Flash 的功能,只需使用 session-put!将值放入会话中,然后使用 session-pop! 删除它。

希望这会有所帮助。

于 2011-06-03T13:17:28.260 回答
1

如果要使用 GAE 提供的 Sessions,可以使用以下

https://gist.github.com/1095841

在您的请求中包含类似环的会话,但基于 GAE 会话支持。

如果你想要有状态会话,你可以使用 Sandbar 提供的有状态会话 API

https://github.com/brentonashworth/sandbar

于 2011-07-23T13:09:14.023 回答