Google App Engine 中的 Sandbar 或 Ring 会话的简单示例

发布于 2024-11-07 10:03:41 字数 379 浏览 6 评论 0 原文

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

因此,一个清晰的示例最好使用 flash-put!、flash-get、session-put!和会话获取。

I'm trying to work out how to get sessions and flash working in Google App Engine. Could someone provide a clear example using either Ring or Sandbar? I think I have sandbar working, specifically it doesn't tell me that Var sandbar.stateful-session/sandbar-flash is unbound and when I dump the handler I get :flash and :session though I'm not certain if that is a sandbar session or a ring one. For completeness I will mention that I am using the latest versions of appengine-magic, ring, hiccup and sandbar. There do not appear to be any incompatibilities or issues.

So a clear example preferably with use of flash-put!, flash-get, session-put! and session-get.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

莫言歌 2024-11-14 10:03:41

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

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!将其删除。

希望这有帮助。

I don't usually like answering my own questions, however in this case I'll make an exception because:

a) There isn't a lot of easy to understand examples out there.

b) It would be nice to have a quick working example for others to use.

Note: appengine-magic is not required here, this will also work with normal ring sessions

Code

;; 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)

How to use it

Navigating to http://127.0.0.1:8080/inc increments the counter in the session and http://127.0.0.1:8080/ will display the value of counter in the session.

wrap-session! is not required for sessions to work, just using

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

will give you working functional sessions. However I wanted to manage my sessions with side-effects and wrap-session! provides that functionality. To use flash like functionality, simply use session-put! to put a value into the session and then use session-pop! to remove it.

Hope that's helpful.

老娘不死你永远是小三 2024-11-14 10:03:41

如果你想使用GAE提供的Session,可以使用下面的

https://gist.github.com/1095841

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

如果您想要在此基础上进行有状态会话,您可以使用 Sandbar 提供的有状态会话 API

https://github.com /布伦托纳什沃思/沙洲

If you want to use the Sessions provided by GAE, you can use the following

https://gist.github.com/1095841

to include a ring like session in your requests, but based on GAE session support.

If you want stateful sessions on top of this, you can use the stateful session API provided by Sandbar

https://github.com/brentonashworth/sandbar

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文