diff --git a/package.json b/package.json index 8f50fa370d7efc71b9fcceba2e8415efdac378f6..0c82550e4cc9732120b2abef664e024e1d15090a 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,9 @@ "protobufjs": "^6.10.1", "typescript": "4.2.4", "url": "^0.11.0", - "webpack": "4" + "webpack": "4", + "websocket": "^1.0.34", + "ws": "^8.5.0" }, "devDependencies": { "@types/chai": "^4.2.18", diff --git a/src/commands/index.ts b/src/commands/index.ts index 8f712620eaac81fdffa8e2a81263f2f328b61f99..c22f96e3bafe2496d40500552318ddecae751c0d 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -53,7 +53,7 @@ const unkownErr = ( export const readMsg = (proto: Proto, data: any): Record<string, any> => { const record = proto.rootRecord.lookupType("usp_record.Record"); - const decodedRecord: any = record.decode(data); + const decodedRecord: any = record.decode('binaryData' in data ? data.binaryData : data); const msg = proto.rootMsg.lookupType("usp.Msg"); const decodedMsg = msg.decode(decodedRecord.noSessionContext.payload); diff --git a/src/configurations/build.ts b/src/configurations/build.ts index 83ce1b70ade6df5a4d516dba07ec78e58ec68777..ab2580f1422c14e4de62da1144116a838584e70b 100644 --- a/src/configurations/build.ts +++ b/src/configurations/build.ts @@ -109,7 +109,7 @@ const buildConnect: BuildConnectionFn = callbackRouter.add("error", handleError); const connectTimeout = options.connectTimeout || defaultConnectionTimeout; - const client = await timeoutWrapper(async () => connectClient(options), connectTimeout); + const client = await timeoutWrapper(() => connectClient(options), connectTimeout); const handleInit = () => new Promise<string>((resolve, reject) => { diff --git a/src/configurations/mqtt.ts b/src/configurations/mqtt.ts index 75319650b47543ebbd899bffbd06cc6cd8737527..4d7658caf06d8bd4dc20e836f104b896671a8402 100644 --- a/src/configurations/mqtt.ts +++ b/src/configurations/mqtt.ts @@ -5,6 +5,7 @@ import { ConnectionClient, URLConnectionOptions, Proto, + ConnectClientFn, } from "../types"; import buildConnect from "./build"; @@ -15,7 +16,7 @@ import rootMsgJson from "../specs/usp-msg-1-1"; const isURL = (opts: ConnectionOptions): opts is URLConnectionOptions => "url" in opts; -const connectClient = (opts: ConnectionOptions): ConnectionClient => +const connectClient: ConnectClientFn = async (opts) => isURL(opts) ? (mqttAsync.connectAsync( opts.url, diff --git a/src/configurations/ws.ts b/src/configurations/ws.ts new file mode 100644 index 0000000000000000000000000000000000000000..d8a0ab72a52fcd37588cc56a8cce7f5a154ad84c --- /dev/null +++ b/src/configurations/ws.ts @@ -0,0 +1,42 @@ +import { client as WebSocketClient } from "websocket"; +import { decodeId } from "../commands"; +import { ConnectionOptions, Proto, ConnectClientFn } from "../types"; + +import buildConnect from "./build"; +import protobuf from "protobufjs"; +import rootRecordJson from "../specs/usp-record-1-1"; +import rootMsgJson from "../specs/usp-msg-1-1"; + +const connectClient: ConnectClientFn = (opts: any) => + new Promise((resolve, reject) => { + const client = new WebSocketClient(); + + client.on("connectFailed", (error) => { + reject(error); + }); + + client.on("connect", (ws) => { + resolve({ + on: (key, responseFn) => ws.on(key, (data) => responseFn(key, data)), + subscribe: (to) => null, + unsubscribe: (from) => null, + publish: (endpoint, msg) => ws.send(msg), + end: ws.close, + }); + }); + + client.connect(`${opts.protocol}://${opts.host}:${opts.port}/usp/endpoint`, "v1.usp"); + }); + +const loadProtobuf = async (): Promise<Proto> => { + const rootRecord = protobuf.Root.fromJSON(rootRecordJson); + const rootMsg = protobuf.Root.fromJSON(rootMsgJson); + const header: any = rootMsg.lookupType("usp.Header"); + return { rootRecord, rootMsg, header }; +}; + +export default buildConnect({ + connectClient, + decodeID: decodeId, + loadProtobuf, +}); diff --git a/src/types.ts b/src/types.ts index f51cd1d5b1a51f1080799fefaa732d5a33a96bfb..9f857e93dd68b67ff15d872ee19b1aded6446332 100644 --- a/src/types.ts +++ b/src/types.ts @@ -556,7 +556,7 @@ export type ConnectionClient = { end: () => void; }; -export type ConnectClientFn = (options: ConnectionOptions) => ConnectionClient; +export type ConnectClientFn = (options: ConnectionOptions) => Promise<ConnectionClient>; export type DecodeIDFn = (data: any) => string; diff --git a/tsconfig.json b/tsconfig.json index 294cce36af59e6f7a76e03d7746f9f44a49158cb..d4d7af920803601ec46181be001a429bbd662c21 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,6 +8,7 @@ "web", "qjs", "src/configurations/quickjs/*", + "src/configurations/ws.ts", "src/qjs-index.ts", "tsconfig.qjs.json", "qjs-compile.js", diff --git a/yarn.lock b/yarn.lock index d295ac79f9fd9935aa45f1002ccf865d7ce76a5d..06deca3b5723eea9a93ac9e9c8ccf5e4cf3dd5e8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -407,9 +407,9 @@ atob@^2.1.2: resolved "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -awesome-typescript-loader@latest: +awesome-typescript-loader@^5.2.1: version "5.2.1" - resolved "https://registry.npmjs.org/awesome-typescript-loader/-/awesome-typescript-loader-5.2.1.tgz" + resolved "https://registry.yarnpkg.com/awesome-typescript-loader/-/awesome-typescript-loader-5.2.1.tgz#a41daf7847515f4925cdbaa3075d61f289e913fc" integrity sha512-slv66OAJB8orL+UUaTI3pKlLorwIvS4ARZzYR9iJJyGsEgOqueMfOMdKySWzZ73vIkEe3fcwFgsKMg4d8zyb1g== dependencies: chalk "^2.4.1" @@ -627,6 +627,13 @@ buffer@^6.0.3: base64-js "^1.3.1" ieee754 "^1.2.1" +bufferutil@^4.0.1: + version "4.0.6" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.6.tgz#ebd6c67c7922a0e902f053e5d8be5ec850e48433" + integrity sha512-jduaYOYtnio4aIAyc6UbvPCVcgq7nYpVnucyxr6eCYg/Woad9Hf/oxxBRDnGGjPfjUm6j5O/uBWhIu4iLebFaw== + dependencies: + node-gyp-build "^4.3.0" + builtin-status-codes@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz" @@ -1833,6 +1840,11 @@ is-stream@^2.0.0: resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== +is-typedarray@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + is-windows@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz" @@ -2281,6 +2293,11 @@ next-tick@~1.0.0: resolved "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz" integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= +node-gyp-build@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.3.0.tgz#9f256b03e5826150be39c764bf51e993946d71a3" + integrity sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q== + node-libs-browser@^2.2.1: version "2.2.1" resolved "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz" @@ -3233,6 +3250,13 @@ type@^2.5.0: resolved "https://registry.npmjs.org/type/-/type-2.5.0.tgz" integrity sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw== +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz" @@ -3337,6 +3361,13 @@ use@^3.1.0: resolved "https://registry.npmjs.org/use/-/use-3.1.1.tgz" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== +utf-8-validate@^5.0.2: + version "5.0.9" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.9.tgz#ba16a822fbeedff1a58918f2a6a6b36387493ea3" + integrity sha512-Yek7dAy0v3Kl0orwMlvi7TPtiCNrdfHNd7Gcc/pLq4BLXqfAmd0J7OWMizUQnTTJsyjKn02mU7anqwfmUP4J8Q== + dependencies: + node-gyp-build "^4.3.0" + util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" @@ -3462,6 +3493,18 @@ webpack@4: watchpack "^1.7.4" webpack-sources "^1.4.1" +websocket@^1.0.34: + version "1.0.34" + resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.34.tgz#2bdc2602c08bf2c82253b730655c0ef7dcab3111" + integrity sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ== + dependencies: + bufferutil "^4.0.1" + debug "^2.2.0" + es5-ext "^0.10.50" + typedarray-to-buffer "^3.1.5" + utf-8-validate "^5.0.2" + yaeti "^0.0.6" + which@2.0.2, which@^2.0.1: version "2.0.2" resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" @@ -3517,6 +3560,11 @@ ws@^7.5.0: resolved "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz" integrity sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w== +ws@^8.5.0: + version "8.5.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" + integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== + xtend@^4.0.0, xtend@^4.0.2, xtend@~4.0.1: version "4.0.2" resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz" @@ -3532,6 +3580,11 @@ y18n@^5.0.5: resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== +yaeti@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577" + integrity sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc= + yallist@^3.0.2: version "3.1.1" resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz"