上一篇文章中讲了远程桌面监控的实现思路。虽然是可用的,但有不少很差用的地方,因而我又进行了完善。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
服务端支持命令行启动,支持参数设置服务器
服务端支持cosmiconfig风格的配置
客户端支持网页的方式
客户端支持命令行启动
修改了键盘和鼠标不许的一些bug
添加了英文的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是eslint还有stylelint实现配置文件查找的方式,你应该会很熟悉,就是以下的配置查找顺序
而后在代码里面读取配置,我封装了一个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"
}
复制代码
以前是服务端直接使用了客户端传递过来的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的,因此作了拦截,这里后续还会作优化,如今只是解决了按键不许的问题。
emmm.这个就不用赘述了。
如今robot-js有的键不支持,而且mac的多指触控也还没作支持,并且性能也须要优化。但已是一个可用的版本了,后续还会继续完善。
欢迎反馈,欢迎star~