我已经使用http-kit设置了一个WebSocket服务器,应该接受web套接字连接。这是http-kit文档中显示的基本示例。
问题是:如何创建一个连接到它的Clojure客户端?
客户端可以是任何Clojure http库,我真的不介意。我已经了解了Javascript客户端,而且我相信Java有一个我可以从Clojure中使用的API。但是我要找的是一个Clojure库,支持websockets 客户端和服务器的。我在http-kit代码中没有看到任何让它变得简单的东西
aleph在服务器端和客户端都支持websockets。要习惯异步风格和aleph的核心抽象可能需要一些时间,但一旦掌握了窍门,它就是一个非常好的工具。
Gniazdo是Clojure的WebSocket客户端。它封装了Jetty的协议实现。
http-kit的客户端还不支持WebSocket(我想不出一个好的API)。对于这种用例,Aleph是一个很好的选择。另一个选项是http.async。我已经在http-kit的服务器的websocket单元测试中使用了它:这里
对于2015年加入我们的人:作为新手,我刚刚花了一些时间尝试了所有可用的不同选项,很难找到一个库来提供一种简单的方法来设置一个简单的Clojure WebSocket客户端。(公平地说,WebSocket客户端在非浏览器/JavaScript环境中运行似乎并不常见,这就是为什么ClojureScript WebSocket客户端似乎如此强调的原因。)
虽然没有很好的文档,但是http.async.client最终成为了对我来说阻力最小的路径。我能够成功地从WebSocket服务器读取流数据,并通过以下操作将其打印到控制台:
(ns example.core
(:require [http.async.client :as async]))
(def url "ws://localhost:1337")
(defn on-open [ws]
(println "Connected to WebSocket."))
(defn on-close [ws code reason]
(println "Connection to WebSocket closed.n"
(format "(Code %s, reason: %s)" code reason)))
(defn on-error [ws e]
(println "ERROR:" e))
(defn handle-message [ws msg]
(prn "got message:" msg))
(defn -main []
(println "Connecting...")
(-> (async/create-client)
(async/websocket url
:open on-open
:close on-close
:error on-error
:text handle-message
:byte handle-message))
;; Avoid exiting until the process is interrupted.
(while true))
结尾的无限循环只是为了防止进程结束。在按Ctrl-C之前,从套接字接收到的消息将被打印到STDOUT。
根据该声明,http-kit支持web套接字。如果没有绑定到http-kit客户机提供的异步功能,也可以使用clj-http。他们有一个非常相似的界面,似乎(我使用但clj-http尚未)。
(ns playground.experiments.ws
(:use aleph.http lamina.core))
(defn ws-client [] (websocket-client {:url "ws://echo.websocket.org:80"}))
(defn echo [message]
(let [channel (wait-for-result (ws-client) 500)]
(enqueue channel message)
(let [echo (wait-for-result (read-channel channel) 500)]
(close channel)
echo)))
(echo "Echo me!")
我构建了一个基本的websocket客户端和服务器,它使用java套接字并包装websocket帧。它的独特之处在于服务器可以同时接受常规套接字连接和websocket连接。
http://github.com/viperscape/gulfstream 客户端代码示例:(def clienthandler
(with-conn server
(send! server "i'm here!")
(with-data server data (prn "client received" data))
(prn "client is now disconnected")))
(def ws-conn-details {:host "ws://echo.websocket.org/chat",:handler clienthandler})
(def client-conn (start-client ws-conn-details))