Node.js 實現遠程桌面監控(二)

描述

上一篇文章中講了遠程桌面監控的實現思路。雖然是可用的,但有不少很差用的地方,因而我又進行了完善。html

我對這個工具的指望是我但願用戶在用的時候,只要經過npm全局安裝一個服務端的包,而後命令行啓動服務端,在另外一臺機器全局安裝客戶端的包,也是命令行啓動,這樣就能夠作到遠程監控了。且命令行支持靈活地參數配置。node

此次迭代後的效果以下: 演示git

如今你同事讓你給幫忙看一個問題的時候,你可讓他github

yarn global add remote-monitor-server
複製代碼

而後web

remote-monitor-server start --port 5555
複製代碼

而後你這邊npm

yarn global add remote-monitor-client-web
複製代碼

而後json

remote-monitor-client-web
複製代碼

就能夠了,你就能夠控制同事的桌面了。有沒有感受使用方式很簡單呢~api

概覽

列一下我作了哪些改動:bash

  1. 服務端支持命令行啓動,支持參數設置服務器

  2. 服務端支持cosmiconfig風格的配置

  3. 客戶端支持網頁的方式

  4. 客戶端支持命令行啓動

  5. 修改了鍵盤和鼠標不許的一些bug

  6. 添加了英文的README

詳述

服務端支持命令行啓動

我調試的時候直接使用node運行的js腳本,後來我一想,用戶也這樣的話就太麻煩了。應該經過圖形界面或者命令行的方式,命令行的方式輕量一些。

實現是使用yargs ,代碼以下:

#!/usr/bin/env node
const yargs = require('yargs');
const conf = require('./Configuration').getInstance();

const script = yargs.scriptName("remote-monitor-server");

script.usage('$0 <cmd> [args]');

script.command('start', '啓動服務器', (yargs) => {
  yargs.option('--port', {
    description: '端口號'
  })
  yargs.option('--monitorScreenshotInterval', {
    description: '截圖間隔'
  })
  yargs.option('--controlEnable', {
    description: '是否容許遠程控制'
  })
  yargs.option('--controlLog', {
    description: '是否打印鼠標鍵盤事件的日誌'
  })
}, function (options) {
  if(options.port) {
    conf.setConfig('server.port', options.port)
  }
  if(options.monitorScreenshotInterval) {
    conf.setConfig('monitor.screenshotInterval', options.monitorScreenshotInterval)
  }
  if(options.controlEnable) {
    conf.setConfig('control.enable', options.controlEnable)
  }
  if(options.controlLog) {
    conf.setConfig('control.log', options.controlLog)
  }
  require('./index');//啓動服務器
})

script.help();
script.argv

複製代碼

在package.json中配置對應的bin字段,這樣安裝這個包的時候,這個文件就會被放到bin目錄下了。

"bin": {
    "remote-monitor-server": "./dist/cli.js"
  }
複製代碼

支持cosmiconfig風格的配置

由於服務端仍是有不少地方須要配置的,好比截圖的時間間隔、是否打印日誌、是否容許客戶端控制等,因此添加了對應的支持。

cosmiconfig是eslint還有stylelint實現配置文件查找的方式,你應該會很熟悉,就是以下的配置查找順序

  • a package.json property
  • a JSON or YAML, extensionless "rc file"
  • an "rc file" with the extensions .json, .yaml, .yml, or .js.
  • a .config.js CommonJS module

而後在代碼裏面讀取配置,我封裝了一個Configuration類,由於全局惟一,因此作成單例:

const cosmiconfig = require('cosmiconfig');
import { get, set } from 'lodash';

const configFinder = cosmiconfig('remoteMonitorServer');

const defaultConfig = {
    monitor: {
        screenshotInterval: 500,// 截圖的間隔
    },
    control: {
        enable: true,// 是否容許客戶端控制
        log: true// 是否打印日誌
    },
    server: {
        port: 3000// 服務器端口號
    }
}

let instance;

class Configuration {
    config: Object;
    constructor() {
        if(instance) {
           return instance;
        }
        this.config = Object.assign({}, defaultConfig, configFinder.searchSync().config);
        instance = this;
    }

    static getInstance() {
        if (!instance) {
            instance = new Configuration();
        }
        return instance;
    }

    getConfig(name) {
        return name ? get(this.config, name) : this.config;
    }
    
    setConfig(name, val) {
        set(this.config, name, val);
    }
}

module.exports = Configuration;

複製代碼

用到配置的地方,經過單例的configuration來讀取配置:

const configuration = require('./Configuration').getInstance();

configuration.getConfig('control.enable')
複製代碼

這是配置文件的方式,固然咱們命令行啓動的的時候經過參數也能夠配置,只須要參數處理的時候設置到configuration對象中就行了

if(options.monitorScreenshotInterval) {
    conf.setConfig('monitor.screenshotInterval', options.monitorScreenshotInterval)
  }
複製代碼

客戶端支持網頁的方式

客戶端只須要展現服務端傳過來的圖片,而且監聽事件而後傳遞到服務端,其實並無用到一些原生的api。使用electron打包成app的方式顯的有些笨重了。因此我單獨打包成了web下的文件,單獨發到npm倉庫,沒有把electron的部分包括進去。

客戶端支持命令行啓動

打包後的客戶端文件只是html還有關聯的js和其餘資源文件,只須要靜態服務器啓動起來就好,因此使用了http-server

#!/usr/bin/env node

const childProcess = require('child_process');
const path = require('path');

childProcess.spawnSync('http-server', [ __dirname ], {
    stdio: 'inherit'
});
複製代碼

而後配置package.json的bin字段

"bin": {
    "remote-monitor-client-web": "index.js"
  }
複製代碼

修改了鍵盤和鼠標不許的一些bug

以前是服務端直接使用了客戶端傳遞過來的keycode來執行事件,但我發現執行的結果是不對的,後來我看robot-js的文檔後,改爲了取robot.KEY_XXX的方式

public executeKeyboardEvent(event: KeyboardEvent): void {
        let keyCode = robot['KEY_' + event.keyName.toUpperCase()];
        if (!keyCode) {
            console.log('robot-js暫不支持' + event.keyName + '鍵');
            return;
        }
        switch(event.type) {
            case 'keydown':
                this.keyboard.press(keyCode);
                break;
            case 'keyup':
                this.keyboard.release(keyCode);
                break;
            case 'keypress':
                this.keyboard.click(keyCode);
                break;
            default:break;
        }
    }
複製代碼

可是有一些鍵,好比方向鍵,robot-js是沒有對應的keyCode的,因此作了攔截,這裏後續還會作優化,如今只是解決了按鍵不許的問題。

添加了英文的README

server readme

client readmd

emmm.這個就不用贅述了。

其餘問題

如今robot-js有的鍵不支持,而且mac的多指觸控也還沒作支持,並且性能也須要優化。但已是一個可用的版本了,後續還會繼續完善。

源碼連接

remote-monitor-server

remote-monitor-client

歡迎反饋,歡迎star~

相關文章
相關標籤/搜索