commit 5a85023702f8524e057793c7aa347f00889051eb Author: Wylie Conlon Date: Wed Nov 7 14:08:35 2018 -0500 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..922ef0f --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.DS_Store +node_modules +dist +.vscode diff --git a/README.md b/README.md new file mode 100644 index 0000000..1bd87a5 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +Sets up a websocket proxy to a JSON-RPC server + +Usage: + +``` +npm install +npm run prepare +node dist/server.js --port 3000 --remotePath localhost --remotePort 2089 +``` + +The only required flag to the server is `--remotePort` diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..a0b0a3f --- /dev/null +++ b/package-lock.json @@ -0,0 +1,162 @@ +{ + "name": "langserver-ws-proxy", + "version": "0.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/node": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-7.10.1.tgz", + "integrity": "sha512-fZvabBkcFJzc+eJN2XTuhKhop1RKdlGQgjmQuxYuQJ6K5rMNoHr6tomb6q0E8Axe+WPyfe/lr7CnnkGvzNh5mA==", + "dev": true + }, + "@types/ws": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-0.0.39.tgz", + "integrity": "sha1-0jhsNHXrZOVhE3okWk0dE7H2n9E=", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + }, + "dependencies": { + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + } + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, + "requires": { + "glob": "^7.0.5" + } + }, + "typescript": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.1.6.tgz", + "integrity": "sha512-tDMYfVtvpb96msS1lDX9MEdHrW4yOuZ4Kdc4Him9oU796XldPYF/t2+uKoX0BBa0hXXwDlqYQbXY5Rzjzc5hBA==", + "dev": true + }, + "vscode-ws-jsonrpc": { + "version": "0.0.2-2", + "resolved": "https://registry.npmjs.org/vscode-ws-jsonrpc/-/vscode-ws-jsonrpc-0.0.2-2.tgz", + "integrity": "sha512-hViHObJHtxD0KX8tvP6QL8fJGfH9mmDrEkdfLKj6Mf1uaxypoMBnjcZDCU3N4l7VriQiNRbohe/FlMrC3/0r7Q==", + "requires": { + "vscode-jsonrpc": "^3.6.0" + }, + "dependencies": { + "vscode-jsonrpc": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.6.2.tgz", + "integrity": "sha512-T24Jb5V48e4VgYliUXMnZ379ItbrXgOimweKaJshD84z+8q7ZOZjJan0MeDe+Ugb+uqERDVV8SBmemaGMSMugA==" + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "ws": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "requires": { + "async-limiter": "~1.0.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..c2b1541 --- /dev/null +++ b/package.json @@ -0,0 +1,22 @@ +{ + "private": true, + "name": "jsonrpc-ws-proxy", + "version": "0.0.1", + "dependencies": { + "vscode-ws-jsonrpc": "^0.0.2-1", + "ws": "^5.0.0" + }, + "devDependencies": { + "@types/node": "^7.10.1", + "@types/ws": "0.0.39", + "minimist": "^1.2.0", + "rimraf": "^2.6.2", + "typescript": "^3.0.1" + }, + "scripts": { + "prepare": "npm run clean && npm run build", + "watch": "tsc -w", + "clean": "rimraf dist", + "build": "tsc", + } +} diff --git a/src/server.ts b/src/server.ts new file mode 100644 index 0000000..002ed80 --- /dev/null +++ b/src/server.ts @@ -0,0 +1,45 @@ +#!/usr/bin/env node + +import * as net from 'net'; +import * as ws from 'ws'; +import * as rpc from 'vscode-ws-jsonrpc'; +import * as rpcServer from 'vscode-ws-jsonrpc/lib/server'; +import * as parseArgs from 'minimist'; + +let argv = parseArgs(process.argv.slice(2)); + +if (argv.help) { + console.log(`Usage: server.js --port 3000 --remotePath localhost -- 2089`); + process.exit(1); +} + +let serverPath : number = parseInt(argv.port) || 3000; +let remotePath : string = argv.remotePath || '127.0.0.1'; +let remotePort : number = parseInt(argv.remotePort); + +if (!remotePort) { + console.log('--remotePort is required'); + process.exit(1); +} + +const wss : ws.Server = new ws.Server({ + port: serverPath, + perMessageDeflate: false +}, () => { + console.log(`Listening to http and ws requests on ${serverPath}`); +}); + +const localSocket = net.connect(remotePort, remotePath, () => { + console.log(`Connected to local server ${remotePath}:${remotePort}`); +}); +const localReader : rpc.SocketMessageReader = new rpc.SocketMessageReader(localSocket); +const localWriter : rpc.SocketMessageWriter = new rpc.SocketMessageWriter(localSocket); +const localConnection : rpcServer.IConnection = rpcServer.createConnection(localReader, localWriter, () => {}); + +wss.on('connection', (client : ws) => { + // The ws interface is compatible with the expected socket interface, except binaryType support + const socket : rpc.IWebSocket = rpc.toSocket(client as any as WebSocket); + const connection : rpcServer.IConnection = rpcServer.createWebSocketConnection(socket); + rpcServer.forward(connection, localConnection); + console.log(`Forwarding new client`); +}); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..b80949f --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "rootDir": "src", + "outDir": "dist", + "baseUrl": ".", + "skipLibCheck": true + }, + "include": [ + "src" + ] +} \ No newline at end of file