-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
124 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
= MQTT broker for Clojure | ||
|
||
== Rationale | ||
|
||
Unfortunately there are few to nothing libraries natively suitable to be used in Clojure development that implement MQTT server side functionalities. | ||
|
||
The Moquette library is Java MQTT broker based on an eventing model with Netty. The library has a good performance and is desegned with embedding support out of the box. Its configuration is compatible with well known Mosquitto Open Source MQTT server. | ||
|
||
Being combained together there and empowered by Clojure - these tools open the way to painless M2M communications for services written in Clojure. | ||
|
||
== Compatibility | ||
|
||
The following implementations are successfully passes production tests: | ||
|
||
- Moquette | ||
- Mosquitto | ||
- Paho | ||
- MQTT.js | ||
- DKD/Brownie | ||
|
||
== Usage | ||
|
||
The usage pattern is simple: | ||
|
||
- define handlers | ||
- create broker instance | ||
- start the service | ||
- serve messages | ||
|
||
=== Defining handlers | ||
|
||
The handlers record should implement `InterceptHandler` interface | ||
|
||
[source, clojure] | ||
---- | ||
(defrecord BasicHandler [id] | ||
InterceptHandler | ||
(onPublish [_ msg] | ||
(let [payload (-> msg .getPayload (.toString StandardCharsets/UTF_8))] | ||
(log/info "Received on topic: " + (.getTopicName msg) + " content: " + payload))) | ||
(getID [_] id) | ||
(getInterceptedMessageTypes [_] InterceptHandler/ALL_MESSAGE_TYPES)) | ||
---- | ||
|
||
The full set of method to be overrided: | ||
|
||
. onPublish | ||
. onConnect | ||
. onDisconnect | ||
. onConnectionLost | ||
. onSubscribe | ||
. onUnsubscribe | ||
. onMessageAcknowledged | ||
. getID | ||
. getInterceptedMessageTypes | ||
|
||
The `ALL_MESSAGE_TYPES` vector contains the whole bunch of the related messages types. | ||
|
||
=== Creating instance | ||
|
||
The library contains default `SimpleBroker` implementation written in Java that requires resources' configuration file name to be passed into construtor. | ||
|
||
In order to manage the instance itnshould be passed as a parameter into the Clojure record implements `CljBroker` interface. | ||
|
||
.CljBroker interface definition | ||
[source, clojure] | ||
---- | ||
(defprotocol CljBroker | ||
(start [o ^InterceptHandler handlers]) | ||
(open [o ^InterceptHandler handlers]) | ||
(stop [o]) | ||
(close [o]) | ||
(send [o from to data qos retain?])) | ||
---- | ||
|
||
so the instantiation of the complete Broker is looks like: | ||
|
||
[source, clojure] | ||
---- | ||
(def config-name "my-broker-settings.conf") | ||
(def srv-java (SimpleBroker. config-name)) | ||
(def srv-clj (Broker. srv-java)) | ||
---- | ||
|
||
=== Starting the service | ||
|
||
The clojure interface support two approaches: | ||
|
||
. controling the instance by calling `start`/`stop` methods (that fully corresponds to its Java interface) | ||
. controling the instance by `with-open` macro | ||
|
||
.start/stop | ||
[source,clojure] | ||
---- | ||
... | ||
(let [srv (Broker. (SimpleBroker. config-name))] | ||
(start srv (BasicHandler. "My Instance")) | ||
;; your code here | ||
(stop srv)) | ||
... | ||
---- | ||
|
||
.with-open | ||
[source,clojure] | ||
---- | ||
... | ||
(with-open [srv (Broker. (SimpleBroker. config-name))] | ||
(start srv (BasicHandler. "My Instance"))) | ||
;; or even | ||
(def config-name "my-broker-settings.conf") | ||
(def srv-java (SimpleBroker. config-name)) | ||
(def srv-clj (Broker. srv-java)) | ||
(with-open [srv (open srv-clj (BasicHandler. "My Instance"))] | ||
(comment "Do your stuff here")) | ||
---- | ||
|
||
== License | ||
|
||
© 2022 Fern Flower Lab | ||
|
||
Distributed under the MIT License. |