使用electron-vue框架,跑起来项目, 参考地址: https://simulatedgreg.gitbooks.io/electron-vue/content/cn/ 跑起来长这样
服务端&客户端已经能实现内网穿透,参考文章:http://lvsige.top/archives/19
如果以上两项都完成了,那么请继续~
一个穿透软件,需要具备的能力:用户安装软件后,只需要填写本地端口号以及期望的域名,点击连接,即可使用域名访问本地文件。
./frpc -c ./frpc.ini
这个命令应该自动完成。用到nodejs里的ini, fs, path
模块。
用nodejs里 child_process
模块。child_process文档
把解压后的frp文件夹放在electron-vue项目里
在主进程里:
const ini = require('ini')
const path = require('path')
const fs = require('fs')
let appPath = path.resolve(__dirname, '../../')
let filePath = path.join(appPath, 'frp', 'frpc.ini')
let config = null
// 开始读取数据
fs.readFile(filePath, (err, data) => {
if (data) {
config = ini.parse(data.toString())
app.config = config
}
})
点击"连接"时, 能够修改frpc.ini
// 写入数据
function writeConfig(config) {
var iniObj = {
common: {
server_addr: 'x.x.x.x',
server_port: 7000,
},
web: {
type: 'http',
local_port: config.port,
custom_domains: `${config.hostname}${config.thost || '.lvsige.top'}`,
},
}
let iniStr = ini.encode(iniObj)
fs.writeFileSync(filePath, iniStr)
}
可以读取写入frpc.ini之后, 就要建立连接了
nodejs里的子进程模块 http://nodejs.cn/api/child_process.html
const exec = require('child_process').exec
ipcMain.on('connectEvent', (event, arg) => {
writeConfig(arg)
zlog.info('接收到参数 开始建立连接')
let filePath = path.join(appPath, 'frp')
workerProcess = exec(
`cd ${filePath}
chmod 755 *
./frpc -c ./frpc.ini
`,
{}
)
// 给当前目录所有文件修改权限为755
// 打印正常的后台可执行程序输出
workerProcess.stdout.on('data', (data) => {
event.sender.send('okAllInfo', data)
zlog.info(data, '打印正常的后台可执行程序输出')
})
// 打印错误的后台可执行程序输出
workerProcess.stderr.on('data', (data) => {
zlog.info(data, '打印错误的后台可执行程序输出')
})
// 退出之后的输出
workerProcess.on('exit', (code) => {
zlog.info('process exit', code)
})
})
关闭断开连接时
// 退出
ipcMain.on('close', (event, arg) => {
zlog.info('断开连接, 收到信号了')
exec('ps -ef|grep frp', function (err, stdout, stderr) {
stdout.split('\n').filter(function (line) {
var p = line.trim().split(/\s+/)
var address = p[1]
if (
address !== undefined &&
address !== 'PID' &&
p.some((item) => {
return item === './frpc.ini'
})
) {
exec('kill ' + address, function (err, stdout, stderr) {
if (err) {
return zlog.info('杀死进程失败!!')
}
event.sender.send('killProcess')
zlog.info('杀死进程成功')
})
}
})
})
})