阅读 918

Node.js 实现远程桌面监控(二)

描述

上一篇文章中讲了远程桌面监控的实现思路。虽然是可用的,但有很多不好用的地方,于是我又进行了完善。

我对这个工具的期望是我希望用户在用的时候,只要通过npm全局安装一个服务端的包,然后命令行启动服务端,在另一台机器全局安装客户端的包,也是命令行启动,这样就可以做到远程监控了。且命令行支持灵活地参数配置。

这次迭代后的效果如下: 演示

现在你同事让你给帮忙看一个问题的时候,你可以让他

yarn global add remote-monitor-server
复制代码

然后

remote-monitor-server start --port 5555
复制代码

然后你这边

yarn global add remote-monitor-client-web
复制代码

然后

remote-monitor-client-web
复制代码

就可以了,你就可以控制同事的桌面了。有没有感觉使用方式很简单呢~

概览

列一下我做了哪些改动:

  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~

关注下面的标签,发现更多相似文章
评论