UNPKG

aws-crt

Version:

NodeJS bindings to the aws-c-* libraries

255 lines 10.9 kB
"use strict"; /* * Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; Object.defineProperty(exports, "__esModule", { value: true }); const binding_1 = __importDefault(require("./binding")); const native_resource_1 = require("./native_resource"); const event_1 = require("../common/event"); const error_1 = require("./error"); const io = __importStar(require("./io")); const util_1 = require("util"); var http_1 = require("./http"); exports.HttpProxyOptions = http_1.HttpProxyOptions; const mqtt_1 = require("../common/mqtt"); var mqtt_2 = require("../common/mqtt"); exports.QoS = mqtt_2.QoS; exports.MqttWill = mqtt_2.MqttWill; class MqttClient extends native_resource_1.NativeResource { constructor(bootstrap) { super(binding_1.default.mqtt_client_new(bootstrap.native_handle())); this.bootstrap = bootstrap; } new_connection(config) { return new MqttClientConnection(this, config); } } exports.MqttClient = MqttClient; const normalize_encoder = new util_1.TextEncoder(); function normalize_payload(payload) { let payload_data; if (payload instanceof DataView) { // If payload is already dataview, just use it payload_data = payload; } else { if (typeof payload === 'object') { // Convert payload to JSON string, next if block will turn it into a DataView. payload = JSON.stringify(payload); } if (typeof payload === 'string') { // Encode the string as UTF-8 payload_data = new DataView(normalize_encoder.encode(payload).buffer); } else { throw new TypeError("payload parameter must be a string, object, or DataView."); } } return payload_data; } class MqttClientConnection extends native_resource_1.NativeResourceMixin(event_1.BufferedEventEmitter) { constructor(client, config) { super(); this.client = client; this.config = config; this._super(binding_1.default.mqtt_client_connection_new(client.native_handle(), (error_code) => { this._on_connection_interrupted(error_code); }, (return_code, session_present) => { this._on_connection_resumed(return_code, session_present); })); this.tls_ctx = config.tls_ctx; } close() { binding_1.default.mqtt_client_connection_close(this.native_handle()); } // Override to allow uncorking on ready on(event, listener) { super.on(event, listener); if (event == 'connect') { process.nextTick(() => { this.uncork(); }); } return this; } connect() { return __awaiter(this, void 0, void 0, function* () { return new Promise((resolve, reject) => { reject = this._reject(reject); const on_connect = (error_code, return_code, session_present) => { if (error_code == 0 && return_code == 0) { resolve(session_present); this.emit('connect', session_present); } else if (error_code != 0) { reject("Failed to connect: " + io.error_code_to_string(error_code)); } else { reject("Server rejected connection."); } }; // If there is a will, ensure that its payload is normalized to a DataView const will = this.config.will ? new mqtt_1.MqttWill(this.config.will.topic, this.config.will.qos, normalize_payload(this.config.will.payload), this.config.will.retain) : undefined; try { binding_1.default.mqtt_client_connection_on_message(this.native_handle(), this._on_any_publish.bind(this)); binding_1.default.mqtt_client_connection_connect(this.native_handle(), this.config.client_id, this.config.host_name, this.config.port, this.config.tls_ctx ? this.config.tls_ctx.native_handle() : null, this.config.socket_options.native_handle(), this.config.keep_alive, this.config.timeout, will, this.config.username, this.config.password, this.config.use_websocket, this.config.proxy_options ? this.config.proxy_options.create_native_handle() : undefined, this.config.clean_session, on_connect, this.config.websocket_handshake_transform); } catch (e) { reject(e); } }); }); } reconnect() { return __awaiter(this, void 0, void 0, function* () { return new Promise((resolve, reject) => { reject = this._reject(reject); function on_connect(error_code, return_code, session_present) { if (error_code == 0 && return_code == 0) { resolve(session_present); } else if (error_code != 0) { reject("Failed to connect: " + io.error_code_to_string(error_code)); } else { reject("Server rejected connection."); } } try { binding_1.default.mqtt_client_connection_reconnect(this.native_handle(), on_connect); } catch (e) { reject(e); } }); }); } publish(topic, payload, qos, retain = false) { return __awaiter(this, void 0, void 0, function* () { return new Promise((resolve, reject) => { reject = this._reject(reject); let payload_data = normalize_payload(payload); function on_publish(packet_id, error_code) { if (error_code == 0) { resolve({ packet_id }); } else { reject("Failed to publish: " + io.error_code_to_string(error_code)); } } try { binding_1.default.mqtt_client_connection_publish(this.native_handle(), topic, payload_data, qos, retain, on_publish); } catch (e) { reject(e); } }); }); } subscribe(topic, qos, on_message) { return __awaiter(this, void 0, void 0, function* () { return new Promise((resolve, reject) => { reject = this._reject(reject); function on_suback(packet_id, topic, qos, error_code) { if (error_code == 0) { resolve({ packet_id, topic, qos, error_code }); } else { reject("Failed to subscribe: " + io.error_code_to_string(error_code)); } } try { binding_1.default.mqtt_client_connection_subscribe(this.native_handle(), topic, qos, on_message, on_suback); } catch (e) { reject(e); } }); }); } unsubscribe(topic) { return __awaiter(this, void 0, void 0, function* () { return new Promise((resolve, reject) => { reject = this._reject(reject); function on_unsuback(packet_id, error_code) { if (error_code == 0) { resolve({ packet_id }); } else { reject("Failed to unsubscribe: " + io.error_code_to_string(error_code)); } } try { binding_1.default.mqtt_client_connection_unsubscribe(this.native_handle(), topic, on_unsuback); } catch (e) { reject(e); } }); }); } disconnect() { return __awaiter(this, void 0, void 0, function* () { return new Promise((resolve, reject) => { reject = this._reject(reject); const on_disconnect = () => { resolve(); this.emit('disconnect'); this.close(); }; try { binding_1.default.mqtt_client_connection_disconnect(this.native_handle(), on_disconnect); } catch (e) { reject(e); } }); }); } // Wrap a promise rejection with a function that will also emit the error as an event _reject(reject) { return (reason) => { reject(reason); this.emit('error', new error_1.CrtError(reason)); }; } _on_connection_interrupted(error_code) { this.emit('interrupt', new error_1.CrtError(error_code)); } _on_connection_resumed(return_code, session_present) { this.emit('resume', return_code, session_present); } _on_any_publish(topic, payload) { this.emit('message', topic, payload); } } exports.MqttClientConnection = MqttClientConnection; //# sourceMappingURL=mqtt.js.map