{"id":16880615,"url":"https://github.com/squaremo/mqtt-broker","last_synced_at":"2025-04-11T11:44:29.848Z","repository":{"id":13137286,"uuid":"15819470","full_name":"squaremo/mqtt-broker","owner":"squaremo","description":"Async non-blocking mqtt server on top of Netty","archived":false,"fork":false,"pushed_at":"2014-01-16T11:06:46.000Z","size":172,"stargazers_count":6,"open_issues_count":0,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-25T08:11:05.649Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/squaremo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-01-11T08:41:44.000Z","updated_at":"2023-05-22T16:54:26.000Z","dependencies_parsed_at":"2022-08-25T17:53:48.915Z","dependency_job_id":null,"html_url":"https://github.com/squaremo/mqtt-broker","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squaremo%2Fmqtt-broker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squaremo%2Fmqtt-broker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squaremo%2Fmqtt-broker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/squaremo%2Fmqtt-broker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/squaremo","download_url":"https://codeload.github.com/squaremo/mqtt-broker/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248387149,"owners_count":21095163,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-13T15:59:30.913Z","updated_at":"2025-04-11T11:44:29.815Z","avatar_url":"https://github.com/squaremo.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MQTT Broker\n\nAn MQTT broker on top of [Netty](netty.io). This is a very early stage\nproject and should be considered experimental.\n\nThe intention is to build a fully async non-blocking MQTT server.\n\n## Motivation\n\nWriting network services used to be hard or expensive. Now it is\nneither, and this is what I want to demonstrate by publishing the code\nof a working broker for the [MQTT](http://mqtt.org) protocol.\n\nOf course, this is not yet a complete implementation of MQTT. It doesn't\ninclude QoS, Last Will and Testament and other feature of the MQTT\nprotocol. It does, however, show how to write a modern scaleable\nservice, using Clojure on the JVM.\n\n## Ingredients\n\n* git\n* Java Virtual Machine\n* [Leiningen](http://leiningen.org/)\n* [GraphViz](http://www.graphviz.org/) (definitely optional)\n* [mosquitto](http://mosquitto.org/) (for testing)\n\n## Method\n\n```\n$ lein repl\n$ (go)\n\n```\n\nOpen a new terminal and run the following\n\n```\nmosquitto_sub -t /test\n```\n\nNow open another terminal to publish messages to the broker, seeing them\nappear in the other terminal.\n\n```\nmosquitto_pub -t /test -m \"Hello\"\n```\n\n## How it works\n\n[resources/config.clj](resources/config.clj) shows you which components make up this system,\nincluding the codec provided by\n[clj-mqtt](https://github.com/xively/clj-mqtt).\n\nThis project depends on [Jig](https://github.com/juxt/jig) which\nprovides the `go` function, which reads the [config.clj](config.clj) file\nand instantiates the components therein. If you have [graphviz]()\ninstalled you can type `(graph)` at the console to view a diagram\nshowing how the components fit together.\n\nWe provide the code to one of these (`MqttHandler`) which injects a\nfunction into the _system map_, a modern Clojure pattern to collate\napplication state into a single data structure.\n\nAnother, `jig.netty/Server`, is specified with its port number\n(1883). This component provides a generic adapter for Netty 5. On start\nup, this component looks across its dependencies to find other\ncomponents to include in the pipeline that it creates when a client\nconnects.\n\n`jig.netty.mqtt/MqttEncoder` and `jig.netty.mqtt/MqttDecoder` are\nadapters for the codec code kindly provided by\n[clj-mqtt](https://github.com/xively/clj-mqtt). This codec further\nreduces the Clojure code we must write, since it converts between\nlow-level Netty byte buffers and (more convenient) Clojure maps.\n\nEach request is handled by the `case` form, dispatching on the :type\nvalue of the map decoded by clj-mqtt :-\n\n```clojure\n(case (:type msg)\n          :connect (.writeAndFlush ctx {:type :connack})\n          :pingreq (.writeAndFlush ctx {:type :pingresp})\n          :subscribe (do (.writeAndFlush ctx {:type :suback})\n                         (swap! subs (fn [subs]\n                                       (reduce #(update-in %1 [%2] conj ctx)\n                                               subs (map first (:topics msg))))))\n          :publish (doseq [ctx (get @subs (:topic msg))]\n                     (.writeAndFlush ctx msg))\n          :disconnect (.close ctx))\n```\n\nThe `:subscribe` handler acknowledges the request and places the context\nin the `subs` map, using the topic as the key and a list of subsribers\nas the value. You can't mutate maps in Clojure without using its STM and\nI've chosen to use an atom. The `:publish` handler looks up the\nsubscribers based on the topic key and writes out the incoming message\nto each of them.\n\n## Caveats\n\nObviously this implementation is extremely threadbare, but I'm\npublishing it now to show the core essence of a broker and as a\nfoundation on which I and others can build the rest of the MQTT broker\nimplementation.\n\n## License\n\nCopyright © 2014 opensensors.io\n\nDistributed under the Eclipse Public License either version 1.0 or (at\nyour option) any later version.\n\nThe use and distribution terms for this software are covered by the [Eclipse Public License 1.0](http://opensource.org/licenses/eclipse-1.0.php) which can be found in the file epl-v10.html at the root of this distribution. By using this software in any fashion, you are agreeing to be bound by the terms of this license. You must not remove this notice, or any other, from this software.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsquaremo%2Fmqtt-broker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsquaremo%2Fmqtt-broker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsquaremo%2Fmqtt-broker/lists"}