如何启用Fulcro WebSocket
我有一个关于如何开始使用Fulcro和WebSocket的基本问题 i) 我从富尔克罗开始。ii)然后添加客户端和服务器位。iii)在我的服务器中,我还添加了一个如何启用Fulcro WebSocket,websocket,fulcro,Websocket,Fulcro,我有一个关于如何开始使用Fulcro和WebSocket的基本问题 i) 我从富尔克罗开始。ii)然后添加客户端和服务器位。iii)在我的服务器中,我还添加了一个com.fulcrologic.fulcro.networking.websocket protocols.WSListener来检测WS客户端何时连接 在WSListener和浏览器的网络控制台之间,我可以看到客户端从未建立WS连接 Fulcro如何建立初始WS连接 之后,如何将服务器推送到客户端 client.cljs (ns
com.fulcrologic.fulcro.networking.websocket protocols.WSListener
来检测WS客户端何时连接
在WSListener
和浏览器的网络控制台之间,我可以看到客户端从未建立WS连接
- Fulcro如何建立初始WS连接李>
- 之后,如何将服务器推送到客户端李>
(ns foo.client
(:require [fulcro.client :as fc]
[foo.ui.root :as root]
[fulcro.client.network :as net]
[fulcro.client.data-fetch :as df]
[com.fulcrologic.fulcro.networking.websockets :as fws]
[com.fulcrologic.fulcro.application :as app]))
;; Neither this nor the below ":websocket (fws/fulcro-websocket-remote {})" works
;; (defonce app (app/fulcro-app {:remotes {:remote (fws/fulcro-websocket-remote {})}}))
(defonce SPA (atom nil))
(defn mount [] (reset! SPA (fc/mount @SPA root/Root "app")))
(defn start [] (mount))
(def secured-request-middleware
;; The CSRF token is embedded via server_components/html.clj
(->
(net/wrap-csrf-token (or js/fulcro_network_csrf_token "TOKEN-NOT-IN-HTML!"))
(net/wrap-fulcro-request)))
(defn ^:export init []
(reset! SPA (fc/make-fulcro-client
{:client-did-mount (fn [foo]
(df/load foo :all-users root/User))
;; This ensures your client can talk to a CSRF-protected server.
;; See middleware.clj to see how the token is embedded into the HTML
:networking {:remote (net/fulcro-http-remote
{:url "/api"
:request-middleware secured-request-middleware})
:websocket (fws/fulcro-websocket-remote {})}}))
(start))
(defrecord FooWSListener []
WSListener
(client-added [this ws-net cid]
(println (str "Listener for dealing with client added events." [ws-net cid])))
(client-dropped [this ws-net cid]
(println (str "listener for dealing with client dropped events." [ws-net cid]))))
(def foo-ws-listener (->FooWSListener))
(def websockets' (atom nil))
(defn query-parser [env query] )
(defstate middleware
:start
(let [websockets (fws/start! (fws/make-websockets
query-parser
{:http-server-adapter (get-sch-adapter)
:parser-accepts-env? true
;; See Sente for CSRF instructions
:sente-options {:csrf-token-fn nil}}))
defaults-config (:ring.middleware/defaults-config config)
legal-origins (get config :legal-origins #{"localhost"})]
(fwsp/add-listener websockets foo-ws-listener)
(reset! websockets' websockets)
(-> not-found-handler
(wrap-api "/api")
(fws/wrap-api websockets)
server/wrap-transit-params
server/wrap-transit-response
(wrap-html-routes)
(wrap-defaults defaults-config)
wrap-gzip)))
中间件.cljs
(ns foo.client
(:require [fulcro.client :as fc]
[foo.ui.root :as root]
[fulcro.client.network :as net]
[fulcro.client.data-fetch :as df]
[com.fulcrologic.fulcro.networking.websockets :as fws]
[com.fulcrologic.fulcro.application :as app]))
;; Neither this nor the below ":websocket (fws/fulcro-websocket-remote {})" works
;; (defonce app (app/fulcro-app {:remotes {:remote (fws/fulcro-websocket-remote {})}}))
(defonce SPA (atom nil))
(defn mount [] (reset! SPA (fc/mount @SPA root/Root "app")))
(defn start [] (mount))
(def secured-request-middleware
;; The CSRF token is embedded via server_components/html.clj
(->
(net/wrap-csrf-token (or js/fulcro_network_csrf_token "TOKEN-NOT-IN-HTML!"))
(net/wrap-fulcro-request)))
(defn ^:export init []
(reset! SPA (fc/make-fulcro-client
{:client-did-mount (fn [foo]
(df/load foo :all-users root/User))
;; This ensures your client can talk to a CSRF-protected server.
;; See middleware.clj to see how the token is embedded into the HTML
:networking {:remote (net/fulcro-http-remote
{:url "/api"
:request-middleware secured-request-middleware})
:websocket (fws/fulcro-websocket-remote {})}}))
(start))
(defrecord FooWSListener []
WSListener
(client-added [this ws-net cid]
(println (str "Listener for dealing with client added events." [ws-net cid])))
(client-dropped [this ws-net cid]
(println (str "listener for dealing with client dropped events." [ws-net cid]))))
(def foo-ws-listener (->FooWSListener))
(def websockets' (atom nil))
(defn query-parser [env query] )
(defstate middleware
:start
(let [websockets (fws/start! (fws/make-websockets
query-parser
{:http-server-adapter (get-sch-adapter)
:parser-accepts-env? true
;; See Sente for CSRF instructions
:sente-options {:csrf-token-fn nil}}))
defaults-config (:ring.middleware/defaults-config config)
legal-origins (get config :legal-origins #{"localhost"})]
(fwsp/add-listener websockets foo-ws-listener)
(reset! websockets' websockets)
(-> not-found-handler
(wrap-api "/api")
(fws/wrap-api websockets)
server/wrap-transit-params
server/wrap-transit-response
(wrap-html-routes)
(wrap-defaults defaults-config)
wrap-gzip)))
websocket连接是在通过websocket remote进行第一次数据传输时进行的
如果要强制连接,可以通过远程发送任何变异来实现:
(:require [com.fulcrologic.fulcro.mutations :refer [defmutation]
[com.fulcrologic.fulcro.components :as comp])
(defmutation connect-socket [_]
(websocket [_] true))
(comment
;; trigger it via repl or a button handler
(comp/transact! foo.client/SPA `[(connect-socket {})]
建立连接后,您可以从服务器进行如下推送:
(:require [com.fulcrologic.fulcro.networking.websocket-protocols :refer [push]])
(let [client-uid (-> @(:connected-uids websockets')
:any
first)]
(push websockets' client-uid :foo-topic {:foo "bar"}))
要在客户端上接收,需要在websocket
远程上定义一个:推送处理程序
:
(defn push-handler [{:keys [topic msg] :as data}]
(log/info "push-handler received: " data))
;; optionally you can listen for websocket state changes
(defn state-callback [before after]
(log/info "state-callback: " {:before before
:after after}))
(defn ^:export init []
(reset! SPA (fc/make-fulcro-client
{:client-did-mount (fn [foo]
(df/load foo :all-users root/User))
:remotes {:remote (net/fulcro-http-remote
{:url "/api"
:request-middleware secured-request-middleware})
:websocket (fws/fulcro-websocket-remote
{:push-handler push-handler
:state-callback state-callback})}}))
(start))
顺便说一句,由于您使用的是提供的模板挂载
,因此您可以使用它在服务器上处理websockets'
:
(defstate websockets'
:start
(fws/start! (fws/make-websockets
query-parser
{:http-server-adapter (get-sch-adapter)
:parser-accepts-env? true})))
通过这种方式,您可以避免这一行:
(重置!WebSocket的WebSocket)
请务必阅读SENT中有关UID和CID的文档。将“用户标识”分配给服务器推送的潜在连接WebSocket集合是在该API中定义的。通常在登录时使用cookies/sessions,这意味着您必须在登录时重新连接websocket。然后您的UID映射可以使用会话来分配一个UID,您可以将其推送到该UID。@roterski感谢您提供了这个答案。我很清楚这些概念。但是我仍然无法用(comp/transact!foo.client/SPA
[(connectsocket{})]”)触发最初的远程调用。我把我最初的Fulcro模板/Websocket尝试放在这里:@roterski谢谢你的提示。我添加了松弛线程,为其他发现这一点的人提供上下文。