简体   繁体   中英

Sharing an atom between Clojure and Clojurescript?

Assume I have a Clojurescript namespace called main with a atom within it called state.

(ns main)

(atom state nil)

I compile my Clojurescript app, run it on a server, fire up the Clojurescript repl and then connect to my server using a browser. Everything works dandy.

In the Clojurescript repl, I can comfirm the usual

> (+ 1 1) 
2
> (js/alert "Hey there") //shows an alert dialog with "Hey there" in the browser
nil
> main.state
(atom nil)

The Clojurescript repl is great for development. So, clearly I can get and (using swap! or reset!) set the value of a Clojurescript atom from a Clojure application. I was wondering if there was a way to have a connection between the value of an atom in my Clojurescript project and a running Clojure application. Perhaps the Clojurescript client connects to a specified port and sends the result to some Clojure server waiting on that port. Simply stated, I was wondering if it might be possible to have a running server application share the value of the state client atom.

Why, you might ask? Well, I was thinking it would be nice to write the value of the state atom to a actual file (state.clj) whenever state is modified in the running Clojurescript application. This way, I could always have a view of the current value of state . I could use something like emacs (global-auto-revert-mode t) to make sure that state.clj buffer was always fairly recent. This is a little like having a debugger.

Beyond that, my real desire is to then make it so that the running Clojure application would also periodically poll state.clj itself. When the server detects that I modified state.clj, it would accept the modification as the new value of the Clojurescript state atom. It would then do something like what the Clojurescript repl does, illustrated in the following pseudo code:

(send-to-client-for-evaluation
  (compile-into-js 
    (reset! 
      main.state 
      the-read-string-value-of-the-content-of-state.clj)))

Basically, I want the ability for the server to have something akin to a shared atom between the client and the server. I want the value of state to be bidirectionally shared between the client and the server. Is any of this possible, or am I just dreaming?

Sure, just make requests to a rest API sending data in EDN format , and voila! If you want to avoid polling, consider running your Jetty or Tomcat behind an Nginx instance to make use of the Nginx HTTP Push Module . I have a somewhat cobwebby example here (this was pre-ClojureScript, so I wrote the client in plain JS). And there is also gifsockets .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM