jarohen / chord

A library designed to bridge the gap between the triad of CLJ/CLJS, web-sockets and core.async.
439 stars 40 forks source link

Error with first time use #23

Closed jmckitrick closed 9 years ago

jmckitrick commented 9 years ago

Here's the error I got, similar to an earlier report:

Opened channel from 127.0.0.1 Exception in thread "async-dispatch-1" java.lang.IllegalArgumentException: No implementation of method: :take! of protocol: #'clojure.core.async.impl.protocols/ReadPort found for class: nil at clojure.core$_cache_protocol_fn.invoke(core_deftype.clj:544) at clojure.core.async.impl.protocols$eval9453$fn9454$G94449461.invoke(protocols.clj:15) at clojure.core.async.impl.ioc_macros$takeBANG.invoke(ioc_macros.clj:955) at pts.server$ws_handler$fn__12878$state_machine10798auto__12879$fn12881.invoke(server.clj:346) at pts.server$ws_handler$fn__12878$state_machine10798auto__12879.invoke(server.clj:346) at clojure.core.async.impl.ioc_macros$run_state_machine.invoke(ioc_macros.clj:945) at clojure.core.async.impl.ioc_macros$run_state_machine_wrapped.invoke(ioc_macros.clj:949) at pts.server$ws_handler$fn__12878.invoke(server.clj:346) at clojure.lang.AFn.run(AFn.java:22) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:744) java.lang.IllegalArgumentException: No implementation of method: :render of protocol: #'compojure.response/Renderable found for class: clojure.core.async.impl.channels.ManyToMany Channel

Unfortunately, that user said he had no problems on Mac, which is what I'm using. Any ideas?

jmckitrick commented 9 years ago

I should add, the example works fine, so I'm not sure what I'm doing wrong....

jarohen commented 9 years ago

Hi Jonathon, thanks for the bug report :)

I recall having seen both of those error messages before - maybe caused by making a vanilla HTTP connection to a route expecting to serve a Websocket? (that might be a red herring, I'm afraid, it was a while back)

Could you paste in a code example?

Cheers,

James

jmckitrick commented 9 years ago

Here's the server-side code:

(defn ws-handler [{:keys [ws-channel] :as req}](println "Opened channel from " %28:remote-addr req)) (go-loop [](when-let [{:keys [message error] :as msg} %28<! ws-channel%29] %28prn "Message: " msg) (>! ws-channel (if error (format "Error: '%s'." (pr-str msg)) {:received (format "You passed: '%s' at %s." (pr-str message) (java.util.Date.))})) (recur))))

and this in the routes:

(GET "/ws" [](-> ws-handler %28wrap-websocket-handler%29))

and this on the client:

(go (let [{:keys [ws-channel error]} (<! (ws-ch ;;"ws://echo.websocket.org" "ws://localhost:3000/ws" {:format :json-kw}))](if error %28js/console.log "Error: " %28pr-str error)) (>! ws-channel "Hello server from client"))))

jarohen commented 9 years ago

Thanks :) Just to check - have you wrapped your route with the chord.http-kit/wrap-websocket-handler middleware?

jmckitrick commented 9 years ago

I think I found the problem. I've been starting my app view lein ring rather than lein run with a main calling http-kit rather than jetty. Grr.

jarohen commented 9 years ago

Ah, no worries :)

Cheers,

James