Clojure WebSocket客户端

19
我已经使用http-kit设置了一个WebSocket服务器,它应该接受WebSocket连接。这是http-kit文档中显示的基本示例。
问题是: 如何创建一个连接到它的Clojure客户端?
客户端可以是任何Clojure http库,我不介意。我已经知道JavaScript客户端,并且我相信Java有一个API,我可以从Clojure使用。但是我正在寻找一个支持WebSocket的Clojure库,既能用于客户端也能用于服务器。我在http-kit代码中看不到任何使它变得容易的东西。

你想使用Clojure WebSocket客户端来简化事情吗?非基于Web的客户端并不是WebSocket的真正用例,这就解释了为什么缺少Clojure客户端。但是,如果你在谷歌上搜索Java WebSocket客户端,看起来你会找到一些,然后也许你可以使用Interop在Clojure中设置Java客户端。 - georgek
我知道这不是通常的用例。我看到了Java的例子,我只想知道在Clojure中是否可以使用现有的库实现。看起来应该是可以的,因为已经存在HTTP客户端。 - user2263578
6个回答

11

aleph支持服务器和客户端上的Websockets。适应异步编程风格和aleph核心抽象可能需要一些时间,但是一旦掌握了它,它是一个非常好的工具。


找到了,谢谢。我之前排除了它,因为函数名很奇怪,但显然是我的错误。 - user2263578

9

http-kit的客户端目前还不支持WebSocket(我想不出一个好的API来实现它)。对于这种情况,Aleph是一个很好的选择。另一个选择是http.async.client,我在http-kit的服务器websocket单元测试中使用过它:这里


作者的回答是:没错! - number23_cn
谢谢您的回答。我已经决定使用Aleph,所以我会坚持使用它。不过,http.async看起来也是一个不错的选择。 - user2263578
2
http-kit 现在支持 WebSockets! - Chiron

9

Gniazdo 是一个用于 Clojure 的 WebSocket 客户端。它封装了Jetty 协议的实现。


8
对于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。

2
对于一个开箱即用的http-kit版本,有一个非常好的聊天应用程序示例,但是对于我们这些在2019年加入的人,您需要更新所有库,因为他们的示例中的某些依赖项已在Java 11中被弃用。我在这里进行了分支并为您完成了这一切。您仍然需要保持无限循环以避免关闭 - 将其添加到chat-handler中。 - Vlad A.
1
正确的方法是将nginx设置为保持WebSockets打开的时间,可以根据需要设置秒数。 - Vlad A.
1
更好的方法是使用一个常量 ping 函数来保持连接活跃。 - Vlad A.

7
根据这个公告,http-kit已支持Web Socket。如果你不受限于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!")

我已经看到了。它支持服务器,但我无法找到创建连接到我的服务器的http-kit客户端的方法(可能有我忽略的明显问题)。异步操作是不错的,但现在并非必需。你是否曾经使用clj-http连接到服务器?还是只有反过来的情况? - user2263578
我连接到本地主机(并从Web API中提取数据),没有记得任何问题。免责声明:我目前对Clojure的经验很少,只是对工具集进行了一些实验。 - i-blis
这正是我正在寻找的...由于某些原因,我无法在文档中找到如何创建客户端的方法。你能给我指一个例子吗? - user2263578
@user2263578 添加了一个代码示例,尽管你肯定已经找到了方法。是的,它使用了aleph。我的错误。 - i-blis

1

我建立了一个基础的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))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接