From 3fd4bdb59dc296ee87fa4a2e0c54c017b0420709 Mon Sep 17 00:00:00 2001 From: Marin Karamihalev <marin.karamihalev@iopsys.eu> Date: Wed, 9 Mar 2022 12:34:04 +0100 Subject: [PATCH] made connectTimeout work --- README.md | 15 ++++++++++----- src/configurations/build.ts | 22 ++++++++++++++++------ src/configurations/iopsys.ts | 20 +++++++++----------- src/types.ts | 9 +++++++++ 4 files changed, 44 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 71dcadd..dcdc52c 100644 --- a/README.md +++ b/README.md @@ -23,10 +23,8 @@ const run = async () => { host: "my.ip.here", username: "username", password: "password", - port: 90001, + port: 9001, protocol: "ws", - fromId: "from::id", - toId: "to::id", }); // Get property @@ -45,13 +43,20 @@ run(); ```javascript // options are based on https://github.com/mqttjs/MQTT.js#mqttconnecturl-options -// they additionaly require fromId and toId, more info: url.here const usp = await connect(options); ``` +> Additional connection options: + +> - fromId: Source ID +> - toId: Destination ID +> - closeOnDisconnect: Close connection if disconnected +> - reconnectsBeforeClosing: Number of times to attempt reconnecting before closing connection +> - connectTimeout: Timeout in milliseconds for connection + - Get - - get object - all object end with a dot + - get object ```javascript await usp.get("Device.Time."); diff --git a/src/configurations/build.ts b/src/configurations/build.ts index de5b3f6..f225c76 100644 --- a/src/configurations/build.ts +++ b/src/configurations/build.ts @@ -21,7 +21,7 @@ const defaultSubscribeEndpoint = "/usp/controller"; const defaultIdEndpoint = "obuspa/EndpointID"; const defaultFromId = "proto::interop-usp-controller"; const defaultConnectionTimeout = 5000; -const idResolveTimeout = 5000; +const defaultIdResolveTimeout = 5000; const fixId = (s: string) => s.split("+").join("%2B"); @@ -95,26 +95,36 @@ const buildConnect: BuildConnectionFn = const router = makeRouter(); const callbackRouter = makeCallbackRouter(); + const handleError = (err: any) => events && events.onError && events.onError(err); - const handleOffline = () => + const handleOffline = () => { events && events.onOffline && events.onOffline(); + client.end(); + }; const handleReconnect = () => events && events.onReconnect && events.onReconnect(); const handleClose = () => events && events.onClose && events.onClose(); callbackRouter.add("error", handleError); - const client = await connectClient(options); + let client: any = null; + const connectTimeout = options.connectTimeout || defaultConnectionTimeout; + + try { + client = await timeoutWrapper(async () => connectClient(options), connectTimeout); + } catch(err) { + throw new Error(`connection timed out(${connectTimeout}ms)`) + } const handleInit = () => new Promise<string>((resolve, reject) => { const id = setTimeout( () => reject({ - errMsg: `toId was not received within timeout(${idResolveTimeout})`, + errMsg: `toId was not received within timeout(${defaultIdResolveTimeout}ms)`, }), - idResolveTimeout + defaultIdResolveTimeout ); client.on("message", (topic, data: any) => { clearTimeout(id); @@ -179,7 +189,7 @@ const buildConnect: BuildConnectionFn = if (options.closeOnDisconnect === true) client.end(); if ( isTrackingReconnects && - reconnectCount > (options.reconnectsBeforeClosing as number) + reconnectCount >= (options.reconnectsBeforeClosing as number) ) client.end(); }); diff --git a/src/configurations/iopsys.ts b/src/configurations/iopsys.ts index e18aa13..2f08030 100644 --- a/src/configurations/iopsys.ts +++ b/src/configurations/iopsys.ts @@ -15,20 +15,18 @@ import rootMsgJson from "../specs/usp-msg-1-1"; const isURL = (opts: ConnectionOptions): opts is URLConnectionOptions => "url" in opts; -const connectClient = (opts: ConnectionOptions): ConnectionClient => { - if (isURL(opts)) - return mqttAsync.connectAsync( - opts.url, - opts as any - ) as unknown as ConnectionClient; - else - return opts.protocol?.startsWith("ws") - ? (mqttAsync.connectAsync( +const connectClient = (opts: ConnectionOptions): ConnectionClient => + isURL(opts) + ? (mqttAsync.connectAsync( + opts.url, + opts as any + ) as unknown as ConnectionClient) + : opts.protocol?.startsWith("ws") + ? (mqttAsync.connectAsync( `${opts.protocol}://${opts.host}:${opts.port}`, opts as any ) as unknown as ConnectionClient) - : (mqttAsync.connectAsync(opts) as unknown as ConnectionClient); -}; + : (mqttAsync.connectAsync(opts) as unknown as ConnectionClient); const loadProtobuf = async (): Promise<Proto> => { const rootRecord = protobuf.Root.fromJSON(rootRecordJson); diff --git a/src/types.ts b/src/types.ts index 3690adb..802396b 100644 --- a/src/types.ts +++ b/src/types.ts @@ -468,8 +468,17 @@ export interface OtherConnectionOptions { ca?: CertType | Object[]; key?: CertType; cert?: CertType; + /** + * Close connection if disconnected + */ closeOnDisconnect?: boolean; + /** + * Number of times to attempt reconnecting before closing connection + */ reconnectsBeforeClosing?: number; + /** + * Timeout in milliseconds for connection + */ connectTimeout?: number; } -- GitLab