Clojure WebSocket Client

Я настроил сервер WebSocket, используя http-kit, который должен принимать подключения через веб-сокет. Это основной пример, показанный в документации http-kit.

Вопрос в том, как создать клиент Clojure, который подключается к нему?

Клиент может быть любой http-библиотекой Clojure, я не против. Я уже знаю о клиентах Javascript и считаю, что у Java есть API, который я мог бы использовать из Clojure. Но я ищу библиотеку Clojure, которая поддерживает веб-сокеты как для клиента, так и для сервера. Я не увидел в коде http-kit ничего, что могло бы облегчить процесс.

6 ответов

Решение

У aleph есть поддержка веб-сокетов как на сервере, так и на клиенте. Может потребоваться некоторое время, чтобы привыкнуть к асинхронному стилю и основным абстракциям aleph, но это очень хороший инструмент, когда вы освоите его.

Gniazdo - это клиент WebSocket для Clojure. Он оборачивает реализацию протокола Jetty.

Клиент http-kit пока не поддерживает WebSocket (я не могу придумать хороший API для него). Aleph - хороший вариант для такого случая использования. Другой вариант - http.async.client, я использовал его в модульном тесте websocket сервера http-kit: здесь

Для тех, кто присоединился к нам в 2015 году: будучи новичком в этом, я потратил некоторое время на то, чтобы опробовать все доступные варианты, и было довольно сложно найти библиотеку, которая обеспечивает простой способ установки простого клиента Clojure WebSocket. (Честно говоря, кажется, что клиент WebSocket не очень часто работает в контексте, не связанном с браузером /JavaScript, и поэтому так много внимания уделяется клиентам ClojureScript WebSocket.)

Хотя это не очень хорошо задокументировано, https://github.com/cch1/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 поддерживает веб-сокеты. Если вы не привязаны к асинхронным средствам, которые предлагает клиент 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. Он уникален тем, что сервер может одновременно принимать как обычные сокет-соединения, так и веб-сокеты.

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))
Другие вопросы по тегам