✨ 支持自定义客户端端口
This commit is contained in:
parent
da36ed9d1b
commit
0460af5c48
@ -4,7 +4,7 @@ consola.info('debug日志:', process.env.DEBUG === '1' ? '开启' : '关闭')
|
||||
|
||||
module.exports = {
|
||||
httpPort: 8082,
|
||||
clientDefaultPort: 22022,
|
||||
defaultClientPort: 22022,
|
||||
uploadDir: path.join(process.cwd(),'app/db'),
|
||||
staticDir: path.join(process.cwd(),'app/static'),
|
||||
sftpCacheDir: path.join(process.cwd(),'app/socket/sftp-cache'),
|
||||
|
@ -25,7 +25,7 @@ async function addHost({
|
||||
let {
|
||||
body: {
|
||||
name, host, index, expired, expiredNotify, group, consoleUrl, remark,
|
||||
port: newPort, username, authType, password, privateKey, credential, command, tempKey
|
||||
port: newPort, clientPort, username, authType, password, privateKey, credential, command, tempKey
|
||||
}
|
||||
} = request
|
||||
// console.log(request)
|
||||
@ -33,7 +33,7 @@ async function addHost({
|
||||
let hostList = await readHostList()
|
||||
let record = {
|
||||
name, host, index, expired, expiredNotify, group, consoleUrl, remark,
|
||||
port: newPort, username, authType, password, privateKey, credential, command
|
||||
port: newPort, clientPort, username, authType, password, privateKey, credential, command
|
||||
}
|
||||
if (record[authType]) {
|
||||
const clearTempKey = await RSADecryptSync(tempKey)
|
||||
@ -54,7 +54,7 @@ async function updateHost({ res, request }) {
|
||||
hosts,
|
||||
id,
|
||||
host: newHost, name: newName, index, oldHost, expired, expiredNotify, group, consoleUrl, remark,
|
||||
port, username, authType, password, privateKey, credential, command, tempKey
|
||||
port, clientPort, username, authType, password, privateKey, credential, command, tempKey
|
||||
}
|
||||
} = request
|
||||
let isBatch = Array.isArray(hosts)
|
||||
@ -80,18 +80,22 @@ async function updateHost({ res, request }) {
|
||||
record[authType] = await AESEncryptSync(clearSSHKey)
|
||||
// console.log(`${ authType }__commonKey加密存储: `, record[authType])
|
||||
}
|
||||
delete oldRecord.monitorData
|
||||
delete record.monitorData
|
||||
newHostList.push(Object.assign(oldRecord, record))
|
||||
}
|
||||
await writeHostList(newHostList)
|
||||
return res.success({ msg: '批量修改成功' })
|
||||
}
|
||||
if (!newHost || !newName || !oldHost) return res.fail({ msg: '参数错误' })
|
||||
|
||||
let hostList = await readHostList()
|
||||
if (!hostList.some(({ host }) => host === oldHost)) return res.fail({ msg: `原实例[${ oldHost }]不存在,请尝试添加实例` })
|
||||
|
||||
let record = {
|
||||
name: newName, host: newHost, index, expired, expiredNotify, group, consoleUrl, remark,
|
||||
port, username, authType, password, privateKey, credential, command
|
||||
port, clientPort, username, authType, password, privateKey, credential, command
|
||||
}
|
||||
if (!hostList.some(({ host }) => host === oldHost)) return res.fail({ msg: `原实例[${ oldHost }]不存在,请尝试添加实例` })
|
||||
|
||||
let idx = hostList.findIndex(({ _id }) => _id === id)
|
||||
const oldRecord = hostList[idx]
|
||||
|
@ -1,7 +1,7 @@
|
||||
const { Server: ServerIO } = require('socket.io')
|
||||
const { io: ClientIO } = require('socket.io-client')
|
||||
const { readHostList } = require('../utils/storage')
|
||||
const { clientDefaultPort } = require('../config')
|
||||
const { defaultClientPort } = require('../config')
|
||||
const { verifyAuthSync } = require('../utils/verify-auth')
|
||||
const { isAllowedIp } = require('../utils/tools')
|
||||
|
||||
@ -16,8 +16,10 @@ async function getClientsInfo(clientSockets) {
|
||||
})
|
||||
hostList
|
||||
.map(({ host, name, clientPort }) => {
|
||||
if (clientSockets.some(item => item.host === host)) return { name, isIo: true } // 已经建立io连接(无论是否连接成功)的host不再重复建立连接,因为存在多次(reconnectionAttempts)的重试机制
|
||||
let clientSocket = ClientIO(`http://${ host }:${ clientPort || clientDefaultPort }`, {
|
||||
// 已经建立io连接(无论是否连接成功)的host不再重复建立连接,因为存在多次(reconnectionAttempts)的重试机制
|
||||
if (clientSockets.some(item => `${ item.host }:${ item.clientPort || defaultClientPort }` === `${ host }:${ clientPort || defaultClientPort }`)) return { name, isIo: true }
|
||||
// console.log(name, 'clientPort:', clientPort)
|
||||
let clientSocket = ClientIO(`http://${ host }:${ clientPort || defaultClientPort }`, {
|
||||
path: '/client/os-info',
|
||||
forceNew: true,
|
||||
timeout: 5000,
|
||||
@ -25,34 +27,35 @@ async function getClientsInfo(clientSockets) {
|
||||
reconnectionAttempts: 1000
|
||||
})
|
||||
// 将与客户端连接的socket实例保存起来,web端断开时关闭这些连接
|
||||
clientSockets.push({ host, name, clientSocket })
|
||||
clientSockets.push({ host, name, clientPort, clientSocket })
|
||||
return {
|
||||
host,
|
||||
name,
|
||||
clientPort,
|
||||
clientSocket
|
||||
}
|
||||
})
|
||||
.forEach((item) => {
|
||||
if (item.isIo) return // console.log('已经建立io连接的host不再重复建立连接', item.name)
|
||||
const { host, name, clientSocket } = item
|
||||
// clientsData[host] = { connect: false }
|
||||
const { host, name, clientPort, clientSocket } = item
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
clientSocket
|
||||
.on('connect', () => {
|
||||
consola.success('client connect success:', host, name)
|
||||
clientSocket.on('client_data', (osData) => {
|
||||
clientsData[host] = { connect: true, ...osData }
|
||||
clientsData[`${ host }:${ clientPort || defaultClientPort }`] = { connect: true, ...osData }
|
||||
})
|
||||
clientSocket.on('client_error', (error) => {
|
||||
clientsData[host] = { connect: true, error: `client_error: ${ error }` }
|
||||
clientsData[`${ host }:${ clientPort || defaultClientPort }`] = { connect: true, error: `client_error: ${ error }` }
|
||||
})
|
||||
})
|
||||
.on('connect_error', (error) => { // 连接失败
|
||||
// consola.error('client connect fail:', host, name, error.message)
|
||||
clientsData[host] = { connect: false, error: `client_connect_error: ${ error }` }
|
||||
clientsData[`${ host }:${ clientPort || defaultClientPort }`] = { connect: false, error: `client_connect_error: ${ error }` }
|
||||
})
|
||||
.on('disconnect', (error) => { // 一方主动断开连接
|
||||
// consola.info('client connect disconnect:', host, name)
|
||||
clientsData[host] = { connect: false, error: `client_disconnect: ${ error }` }
|
||||
clientsData[`${ host }:${ clientPort || defaultClientPort }`] = { connect: false, error: `client_disconnect: ${ error }` }
|
||||
})
|
||||
})
|
||||
}
|
||||
|
3
web/src/config/index.js
Normal file
3
web/src/config/index.js
Normal file
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
defaultClientPort: 22022
|
||||
}
|
@ -1,8 +1,11 @@
|
||||
import { io } from 'socket.io-client'
|
||||
import { defineStore, acceptHMRUpdate } from 'pinia'
|
||||
import $api from '@/api'
|
||||
import config from '@/config'
|
||||
// import ping from '@/utils/ping'
|
||||
|
||||
const { defaultClientPort } = config
|
||||
|
||||
const useStore = defineStore({
|
||||
id: 'global',
|
||||
state: () => ({
|
||||
@ -42,7 +45,7 @@ const useStore = defineStore({
|
||||
await this.getHostList()
|
||||
await this.getSSHList()
|
||||
await this.getScriptList()
|
||||
this.wsHostStatus()
|
||||
this.wsClientsStatus()
|
||||
},
|
||||
async getHostList() {
|
||||
let { data: newHostList } = await $api.getHostList()
|
||||
@ -80,7 +83,7 @@ const useStore = defineStore({
|
||||
// })
|
||||
// }, 2000)
|
||||
// },
|
||||
async wsHostStatus() {
|
||||
async wsClientsStatus() {
|
||||
// if (this.HostStatusSocket) this.HostStatusSocket.close()
|
||||
let socketInstance = io(this.serviceURI, {
|
||||
path: '/clients',
|
||||
@ -96,8 +99,8 @@ const useStore = defineStore({
|
||||
socketInstance.on('clients_data', (data) => {
|
||||
// console.log(data)
|
||||
this.hostList.forEach(item => {
|
||||
const { host } = item
|
||||
return Object.assign(item, { monitorData: Object.freeze(data[host]) })
|
||||
const { host, clientPort } = item
|
||||
return Object.assign(item, { monitorData: Object.freeze(data[`${ host }:${ clientPort || defaultClientPort }`]) })
|
||||
})
|
||||
})
|
||||
socketInstance.on('token_verify_fail', (message) => {
|
||||
|
@ -127,7 +127,7 @@
|
||||
<el-input
|
||||
v-model="hostForm.privateKey"
|
||||
type="textarea"
|
||||
:rows="5"
|
||||
:rows="3"
|
||||
clearable
|
||||
autocomplete="off"
|
||||
style="margin-top: 5px;"
|
||||
@ -183,7 +183,7 @@
|
||||
<el-input
|
||||
v-model="hostForm.command"
|
||||
type="textarea"
|
||||
:rows="5"
|
||||
:rows="3"
|
||||
clearable
|
||||
autocomplete="off"
|
||||
placeholder="连接服务器后自动执行的指令(例如: sudo -i)"
|
||||
@ -218,6 +218,14 @@
|
||||
@keyup.enter="handleSave"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item key="clientPort" label="客户端端口" prop="clientPort">
|
||||
<el-input
|
||||
v-model.trim.number="hostForm.clientPort"
|
||||
clearable
|
||||
placeholder="客户端上报信息端口(默认22022)"
|
||||
autocomplete="off"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="!isBatchModify"
|
||||
key="index"
|
||||
@ -291,6 +299,7 @@ const formField = {
|
||||
password: '',
|
||||
privateKey: '',
|
||||
credential: '', // credentials -> _id
|
||||
clientPort: '22022',
|
||||
index: 0,
|
||||
expired: null,
|
||||
expiredNotify: false,
|
||||
@ -313,6 +322,7 @@ const rules = computed(() => {
|
||||
name: { required: !isBatchModify.value, message: '输入实例别名', trigger: 'change' },
|
||||
host: { required: !isBatchModify.value, message: '输入IP/域名', trigger: 'change' },
|
||||
port: { required: !isBatchModify.value, type: 'number', message: '输入ssh端口', trigger: 'change' },
|
||||
clientPort: { required: false, type: 'number', message: '输入ssh端口', trigger: 'change' },
|
||||
index: { required: !isBatchModify.value, type: 'number', message: '输入数字', trigger: 'change' },
|
||||
// password: [{ required: hostForm.authType === 'password', trigger: 'change' },],
|
||||
// privateKey: [{ required: hostForm.authType === 'privateKey', trigger: 'change' },],
|
||||
|
Loading…
x
Reference in New Issue
Block a user