Giter Club home page Giter Club logo

mqtt.ts's Introduction

MQTT.ts

This is an implementation of the MQTT 3.1.1 protocol written in TypeScript.

It is not a port of the excellent MQTT.js package. I wrote it for "fun", originally using Flow, but never finished and then forgot about it. When I saw there were no MQTT modules for Deno, I decided to convert it to TypeScript as an exercise in learning Deno.

Since the core of the library has no dependencies, it wasn't too difficult to add support for Node.js and browsers so why not?

Quick Start

import { Client } from 'https://deno.land/x/mqtt/deno/mod.ts'; // Deno (ESM)
// const { Client } = require('@jdiamond/mqtt'); // Node.js (CommonJS)
// import { Client } from 'https://unpkg.com/@jdiamond/mqtt-browser'; // Browsers (ESM)

const client = new Client({ url: 'mqtt://test.mosquitto.org' }); // Deno and Node.js
// const client = new Client({ url: 'ws://test.mosquitto.org:8081' }); // Browsers

await client.connect();

await client.subscribe('incoming/#');

client.on('message', (topic, payload) => {
  console.log(topic, payload);
});

await client.publish('my/topic', 'my payload');

await client.disconnect();

See the API documentation for more details.

Deno

The "raw" TypeScript files are import'able by Deno.

The Deno Client uses Deno.connect to create TCP connections so --allow-net is required when running code using this module.

Look in examples/deno to see examples of using the client.

There are some CLI tools in tools that are similar to mosquitto_pub and mosquitto_sub.

To subscribe:

deno run --allow-net tools/sub.ts -u mqtt://test.mosquitto.org -t "MQTT.ts/test/topic" -v

To publish:

deno run --allow-net tools/pub.ts -u mqtt://test.mosquitto.org -t "MQTT.ts/test/topic" -m "hello"

Node.js

The Node.js Client uses the net module to create TCP connections.

This build is published to npm as @jdiamond/mqtt and can be imported like any normal npm package.

Examples in examples/node.

Browsers

The browser Client uses a WebSocket object to connect to a broker that supports MQTT over WebSockets.

This build is published to npm as @jdiamond/mqtt-browser and available via unpkg.com here:

https://unpkg.com/@jdiamond/mqtt-browser

The UMD build for older browsers is available here:

https://unpkg.com/browse/@jdiamond/mqtt-browser/index.min.js

Example in examples/browser.

Development

First started working with Deno 1.0.0, but I only test with recent versions (most recently 1.24.1). Maybe I should set up some GitHub actions?

To lint, check types, and run tests:

deno lint
deno task tsc
deno test

# Or, run all with:
deno task check

To run a local broker on macOS:

brew install mosquitto
/usr/local/sbin/mosquitto -c mosquitto-mac.conf

To run a local broker on Ubuntu in WSL2:

sudo apt-add-repository ppa:mosquitto-dev/mosquitto-ppa
sudo apt update
sudo apt install mosquitto
mosquitto -c mosquitto-wsl2-ubuntu.conf

To test publishing and subscribing to your local broker, run these commands in separate shells:

deno run --allow-net tools/sub.ts -t "foo/#" -v
deno run --allow-net tools/pub.ts -t "foo/bar" -m "baz"

To make a release:

deno task check

cd browser
# update version in package.json
npm install
npm run build
npm publish
cd ..

cd node
# update version in package.json
npm install
npm run build
npm publish
cd ..

git tag x.y.z
git push --tags

Protocol Links

Roadmap to 1.0

  • finish API docs
  • protocol version 3.1
  • mqtts for deno and node clients
  • use native event target/emitter classes
  • events for messages matching topic filters
  • async iterators for messages matching topic filters
  • make disconnect wait until all publishes sent/acknowledged
  • address all TODO comments in code
  • release process
    • tag for deno.land/x to use
    • publish Node.js and browser builds to npm
      • keep in sync or allow versions to drift?

Post 1.0

  • protocol version 5.0
  • round robin connect to multiple brokers
  • benchmarking and performance improvements
  • MQTT over QUIC
  • base class for server applications?

mqtt.ts's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

mqtt.ts's Issues

Support for cafile certificates

The server I use employs MQTTS and uses a certificate file. When I connect using mosquitto_sub I include the --cafile flag and pass my certificate file. Is this functionality supported in your tool?

d.ts for node or browser?

Hey. Thanks for the library! I am converting my IoT pet project to it from MQTT.js. Also great work on typesafe adaptation for a node using "deno bundle" and babel. Did you find any way to export the declaration files from source that could be distributed along with packages for the node and browser?

Error: connect timer should not be timing out in connected state

Since Deno 1.22.3 started having these errors very frequently. Also happens on the latest version 1.23.0

Error: connect timer should not be timing out in connected state
    at Client.connectTimedOut (https://deno.land/x/[email protected]/client/base_client.ts:949:15)
    at https://deno.land/x/[email protected]/client/base_client.ts:938:14
    at https://deno.land/x/[email protected]/client/base_client.ts:1108:7
    at Object.action (deno:ext/web/02_timers.js:141:13)
    at handleTimerMacrotask (deno:ext/web/02_timers.js:58:12)

Errors when importing module

Tried importing into a simple js file and the following errors flagged:

Check file:///home/codio/workspace/deno_sub.js
error: TS1205 [ERROR]: Re-exporting a type when the '--isolatedModules' flag is provided requires using 'export type'.
  ConnectPacket,
  ~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/packets/mod.ts:37:3

TS1205 [ERROR]: Re-exporting a type when the '--isolatedModules' flag is provided requires using 'export type'.
  ConnackPacket,
  ~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/packets/mod.ts:38:3

TS1205 [ERROR]: Re-exporting a type when the '--isolatedModules' flag is provided requires using 'export type'.
  PublishPacket,
  ~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/packets/mod.ts:39:3

TS1205 [ERROR]: Re-exporting a type when the '--isolatedModules' flag is provided requires using 'export type'.
  PubackPacket,
  ~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/packets/mod.ts:40:3

TS1205 [ERROR]: Re-exporting a type when the '--isolatedModules' flag is provided requires using 'export type'.
  PubrecPacket,
  ~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/packets/mod.ts:41:3

TS1205 [ERROR]: Re-exporting a type when the '--isolatedModules' flag is provided requires using 'export type'.
  PubrelPacket,
  ~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/packets/mod.ts:42:3

TS1205 [ERROR]: Re-exporting a type when the '--isolatedModules' flag is provided requires using 'export type'.
  PubcompPacket,
  ~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/packets/mod.ts:43:3

TS1205 [ERROR]: Re-exporting a type when the '--isolatedModules' flag is provided requires using 'export type'.
  SubscribePacket,
  ~~~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/packets/mod.ts:44:3

TS1205 [ERROR]: Re-exporting a type when the '--isolatedModules' flag is provided requires using 'export type'.
  SubackPacket,
  ~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/packets/mod.ts:45:3

TS1205 [ERROR]: Re-exporting a type when the '--isolatedModules' flag is provided requires using 'export type'.
  UnsubscribePacket,
  ~~~~~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/packets/mod.ts:46:3

TS1205 [ERROR]: Re-exporting a type when the '--isolatedModules' flag is provided requires using 'export type'.
  UnsubackPacket,
  ~~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/packets/mod.ts:47:3

TS1205 [ERROR]: Re-exporting a type when the '--isolatedModules' flag is provided requires using 'export type'.
  PingreqPacket,
  ~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/packets/mod.ts:48:3

TS1205 [ERROR]: Re-exporting a type when the '--isolatedModules' flag is provided requires using 'export type'.
  PingresPacket,
  ~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/packets/mod.ts:49:3

TS1205 [ERROR]: Re-exporting a type when the '--isolatedModules' flag is provided requires using 'export type'.
  DisconnectPacket,
  ~~~~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/packets/mod.ts:50:3

TS1243 [ERROR]: 'async' modifier cannot be used with 'abstract' modifier.
  protected abstract async open(url: URL): Promise<void>;
                     ~~~~~
    at https://deno.land/x/[email protected]/client/base_client.ts:589:22

TS1243 [ERROR]: 'async' modifier cannot be used with 'abstract' modifier.
  protected abstract async write(bytes: Uint8Array): Promise<void>;
                     ~~~~~
    at https://deno.land/x/[email protected]/client/base_client.ts:591:22

TS1243 [ERROR]: 'async' modifier cannot be used with 'abstract' modifier.
  protected abstract async close(): Promise<void>;
                     ~~~~~
    at https://deno.land/x/[email protected]/client/base_client.ts:593:22

Found 17 errors.

npm run build failed for browser

build failed in browser

src/client/publish_test.ts
error TS2318: Cannot find global type 'AsyncIterableIterator'.

src/client/base_client.ts:129:23 - error TS2304: Cannot find name 'AsyncIterable'.

129   abstract iterate(): AsyncIterable<PublishPacket | PubrelPacket>;
                          ~~~~~~~~~~~~~

src/client/base_client.ts:129:23 - error TS4055: Return type of public method from exported class has or is using private name 'AsyncIterable'.

129   abstract iterate(): AsyncIterable<PublishPacket | PubrelPacket>;
                          ~~~~~~~~~~~~~

src/client/base_client.ts:147:21 - error TS2304: Cannot find name 'AsyncIterable'.

147   async *iterate(): AsyncIterable<PublishPacket | PubrelPacket> {
                        ~~~~~~~~~~~~~

src/client/base_client.ts:147:21 - error TS4055: Return type of public method from exported class has or is using private name 'AsyncIterable'.

147   async *iterate(): AsyncIterable<PublishPacket | PubrelPacket> {
                        ~~~~~~~~~~~~~


Found 5 errors.

Support for ReactNative

Hi, thank you for build this library.

Currently, don't have any library good enough to use MQTT in ReactNative. Some libraries are using native libraries (Object-C/Java) to implement then wrap APIs in Javascript (MQTT over TCP: https://github.com/davesters/rn-native-mqtt). Some libraries are fork from the unmaintained library and didn't update anymore (MQTT over Websocket: https://github.com/rh389/react-native-paho-mqtt).

Until I found your work!

Support RN is simple, they have WebSocket API implement. Only a few things need to do, implement UTF Encoder/Decoder, and URL polyfill (whatwg-url-without-unicode)

Can't use MQTT.ts

When importing the library as illustrated in the README I get the following error.

Check file:///home/ahmed/projects/embedded/iot_project/server/main.ts
error: TS1205 [ERROR]: Re-exporting a type when the '--isolatedModules' flag is provided requires using 'export type'.
  ConnectPacket,
  ~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/packets/mod.ts:37:3

TS1205 [ERROR]: Re-exporting a type when the '--isolatedModules' flag is provided requires using 'export type'.
  ConnackPacket,
... [others (same error)]

When I run with --no-check I get the following

error: Uncaught SyntaxError: The requested module './puback.ts' does not provide an export named 'PubackPacket'
import puback, { PubackPacket } from './puback.ts';
~~~~~~~~~~~~
    at <anonymous> (<https://deno.land/x/[email protected]/packets/mod.ts>:6:1)

Deno version

deno 1.6.2 (release, x86_64-unknown-linux-gnu)
v8 8.8.278.2
typescript 4.1.3

PS: This is my first time using Deno

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.