UNPKG

iopa-tcp

Version:

API-First Transport Control Protocol (TCP) stack for Internet of Things (IoT), based on Internet of Protocols Alliance (IOPA) specification

124 lines (106 loc) 4.03 kB
/* * Copyright (c) 2016 Internet of Protocols Alliance (IOPA) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License 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. */ const net = require('net'), iopa = require('iopa-rest'), iopaStream = require('iopa-common-stream'), IOPA = iopa.constants.IOPA, SERVER = iopa.constants.SERVER const packageVersion = require('../../package.json').version; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** * Creates a new IOPA Request using a Tcp Url including host and port name * * @method TcpClient * @parm {object} options not used * @parm {string} urlStr url representation of ://127.0.0.1:8200 * @public * @constructor */ function TcpClient(app) { _classCallCheck(this, TcpClient); var client = this; client._connections = {}; app.properties[SERVER.Capabilities][IOPA.CAPABILITIES.Tcp] = {}; app.properties[SERVER.Capabilities][IOPA.CAPABILITIES.Tcp][SERVER.Version] = packageVersion; } /** * Dispatches a Tcp Request * * @method dispatch * @parm {object} options not used * @parm {string} urlStr url representation of ://127.0.0.1:8200 * @public * @constructor */ TcpClient.prototype.dispatch = function TcpClient_dispatch(channelContext, next) { var client = this; var self = this; return new Promise(function (resolve, reject) { var socket = net.createConnection( channelContext[SERVER.RemotePort], channelContext[SERVER.RemoteAddress], function () { channelContext[SERVER.RawStream] = socket; channelContext[SERVER.RawTransport] = socket; channelContext[SERVER.LocalAddress] = socket.localAddress; channelContext[SERVER.LocalPort] = socket.localPort; channelContext.response[SERVER.RawStream] = socket; channelContext.response[SERVER.LocalAddress] = socket.localAddress; channelContext.response[SERVER.LocalPort] = socket.localPort; socket.once('finish', self._onDisconnect.bind(self, client, channelContext, null)); socket.once('error', self._onDisconnect.bind(self, client, channelContext)); channelContext[SERVER.SessionId] = channelContext[SERVER.LocalAddress] + ":" + channelContext[SERVER.LocalPort] + "-" + channelContext[SERVER.RemoteAddress] + ":" + channelContext[SERVER.RemotePort]; client._connections[channelContext[SERVER.SessionId]] = channelContext; resolve(channelContext); }); }); //ignore next }; /** * @method _onDisconnect * Called when a TCP channel connection is disconnected * * @public */ TcpClient.prototype._onDisconnect = function TcpClient_onDisconnect(client, channelContext, err) { if (channelContext[SERVER.CancelToken].isCancelled) return; channelContext[IOPA.Events] = null; channelContext[SERVER.CancelTokenSource].cancel(IOPA.EVENTS.Disconnect); delete client._connections[channelContext[SERVER.SessionId]]; setTimeout(function () { channelContext[SERVER.RawTransport].destroy(); channelContext.dispose(); }, 100); } /** * @method _onClose * Close the underlying client sockets and stop listening for data * * @returns {Promise()} * @public */ TcpClient.prototype._onClose = function TcpClient_onClose(client) { for (var key in client._connections) this._disconnect(client._connections[key], null); client._connections = {}; return new Promise(function (resolve) { setTimeout(function () { resolve(null); }, 200); }); }; module.exports = TcpClient;