Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

An MQTT-library for ClojureScript

License

NotificationsYou must be signed in to change notification settings

eval/otarta

Repository files navigation

Canonical repository:https://gitlab.com/eval/otarta

cljdoc badgecljdoc badgediscuss at Clojurians-Zulippipeline statusClojars Project

An MQTT-library for ClojureScript.

NOTE: this is pre-alpha software with an API that will change (see theCHANGELOG for breaking changes)

Installation

Leiningen:

[eval/otarta"0.3.1"]

Deps:

eval/otarta {:mvn/version"0.3.1"}

Examples

Usage

The following code assumes:

  • being in a browser (iejs/WebSockets exists. For Node.jssee below.)
  • a websocket-enabled MQTT-broker onlocalhost:9001 (eg viadocker run --rm -ti -p 9001:9001 toke/mosquitto)
(nsexample.core  (:require-macros [cljs.core.async.macros:refer [go go-loop]])  (:require [cljs.core.async:as a:refer [<!]]            [otarta.core:as mqtt]))(defonceclient (mqtt/client"ws://localhost:9001/mqtt#weather-sensor"))(defnsubscription-handler [ch]  (go-loop []    (when-let [m (<! ch)];; example m: {:topic "temperature/current" :payload "12.1" :retain? false :qos 0}      (prn"Received:" m)      (recur))))(go  (let [[err {sub-ch:ch}] (<! (mqtt/subscribe client"temperature/#"))]    (if err      (println"Failed to subscribe:" err)      (do        (println"Subscribed!")        (subscription-handler sub-ch))))  (mqtt/publish client"temperature/current""12.1"))

client

broker-url

The first argument (thebroker-url) should be of the formws(s):://(user:pass@)host.org:1234/path(#some/root/topic).

The fragment contains theroot-topic and indicates the topic relative to which the client publishes and subscribes. This allows for pointing the client to a specific subtree of the broker (eg where it has read/write-permissions, or where it makes sense given the stage:ws://some-broker/mqtt#acceptance/sensor1).

When you write a client that receives its broker-url from outside (ie as an environment variable), it might lack a root-topic. In order to prevent unwanted effects in that case (eg the client subscribing to "#" essentially subscribing to theroot of the broker) you can provide adefault-root-topic:

(mqtt/client config.broker-url {:default-root-topic"weather-sensor"})

The client will then treat the broker-urlws://localhost:9001/mqtt likews://localhost:9001/mqtt#weather-sensor.Whenconfig.broker-url does contain aroot-topic, thedefault-root-topic is ignored (but gives a nice hint as to what theroot-topic could look like, egacceptance/weather-sensor).

messages

Messages have the following shape:

{:topic"temperature/current";; topic relative to `root-topic`:payload"12.1";; formatted payload:retain?false;; whether this message was from the broker's store or 'real-time' from publisher:qos0};; quality of service (0: at most once, 1: at least once, 2: exactly once)

retain?

NOTE:retain? is not so much a property of the sent message, but tells youwhen you received it: typically you receive messages with{:retain? true} directly after subscribing. But when you're subscribed and a message is published with the retain-flag set, the message you'll received has{:retain? false}. This as you received it 'first hand' from the publisher, not from the broker's store.

formats

When publishing or subscribing you can specify a format. Available formats are:string (default),raw,json,edn andtransit:

(go  (let [[err {sub-ch:ch}] (<! (mqtt/subscribe client"temperature/#" {:format:transit}))]    (if err      (println"Failed to subscribe:" err)      (do        (prn (<! sub-ch)))));; prints: {:created-at #inst "2018-09-27T13:13:21.932-00:00", :value 12.1}  (mqtt/publish client"temperature/current" {:created-at (js/Date.):value12.1} {:format:transit}))

Incoming messages with a payload that is not readable, won't appear on the subscription-channel.
Similarly, when formatting fails when publishing, you'll receive an error:

(let [[err _] (<! (mqtt/publish client"foo"#"not transit!" {:format:transit}))]  (when err    (println err)))

You can provide your own format:

(nsexample.core  (:require [otarta.format:as mqtt-fmt]))(defnextract-temperature []...);; this format piggybacks on the string-format;; after which extract-temperature will get the relevant data.;; Otarta will catch any exceptions that occur when reading/writing.(defcustom-format  (reify mqtt-fmt/PayloadFormat    (-read [_fmt buff]      (->> buff (mqtt-fmt/-read mqtt-fmt/string) extract-temperature))    (-write [_fmt v]      (->> v (mqtt-fmt/-write mqtt-fmt/string)))))

Node.js

You should provide a W3C compatible websocket when running via Node.js.
I've had good experience withthis websocket-library (>= v1.0.28).

With the library included in your project (seehttps://clojurescript.org/guides/webpack for details), the following will initializejs/WebSocket:

(nsexample.core  (:require [websocket]))(set! js/WebSocket (.-w3cwebsocket websocket))

Limitations

  • only QoS 0
  • only clean-session
  • no reconnect built-in
  • untested for large payloads (ie more than a couple of KB)

Development

Testing

Viacljs-test-runner:

Viacljs-test-runner:

# once$ clojure -Atest# watching$ clojure -Atest-watch# specific tests(deftest ^{:focus true} only-this-test ...)$ clojure -Atest-watch -i :focus# more options:$ clojure -Atest-watch --help

Figwheel

# start figwheel$ make figwheel# wait till compiled and then from other shell:$ node target/app.js# then from emacs:# M-x cider-connect with host: localhost and port: 7890# from repl:user> (figwheel/cljs-repl);; prompt changes to:cljs.user>;; to quickly see what otarta can do:;; - evaluate the otarta.main namespace;; -theneval the comment-section of otarta.main line by line

SeeCIDER docs what you can do.

Release

Install locally

  • (ensure no CLJ_CONFIG and MAVEN_OPTS env variables are set - this to target ~/.m2)
  • ensure dependencies in pom.xml up to date
    • clj -Spom
  • ensure pom.xml with new version
    • cp pom.xml{.template,}
    • gsed -i 's/$RELEASE_VERSION/1.2.3/' pom.xml
  • make mvn-install
  • testdrive locally

Deploy to Clojars

  • create (pre-)tag
  • push to CI

License

Copyright (c) 2018 Gert Goet, ThinkCreate
Copyright (c) 2018 Alliander N.V.SeeLICENSE.

For licenses of third-party software that this software uses, seeLICENSE-3RD-PARTY.

About

An MQTT-library for ClojureScript

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp