109 lines
3.0 KiB
TypeScript
109 lines
3.0 KiB
TypeScript
import net from 'node:net'
|
|
import { appendLog, cleanData } from '../ultils/helper.js'
|
|
|
|
interface LineConfig {
|
|
id: number
|
|
port: number
|
|
ip: string
|
|
name: string
|
|
output: string
|
|
status: string
|
|
}
|
|
|
|
export default class StationConnection {
|
|
public client: net.Socket
|
|
public config: LineConfig
|
|
|
|
constructor(config: LineConfig) {
|
|
this.config = config
|
|
this.client = new net.Socket()
|
|
}
|
|
|
|
connect(timeoutMs = 5000) {
|
|
return new Promise<void>((resolve, reject) => {
|
|
const { ip, port, name } = this.config
|
|
let resolvedOrRejected = false
|
|
// Set timeout
|
|
this.client.setTimeout(timeoutMs)
|
|
console.log(`🔌 Connecting to station ${name} (${ip}:${port})...`)
|
|
this.client.connect(port, ip, () => {
|
|
if (resolvedOrRejected) return
|
|
resolvedOrRejected = true
|
|
|
|
console.log(`[${Date.now()}] ✅ Connected to line ${name} (${ip}:${port})`)
|
|
setTimeout(() => {
|
|
this.config.status = 'connected'
|
|
resolve()
|
|
}, 1000)
|
|
})
|
|
|
|
this.client.on('data', (data) => {
|
|
let message = data.toString()
|
|
if (message.includes('--More--')) this.writeCommand(' ')
|
|
this.config.output += cleanData(message)
|
|
this.config.output = this.config.output.slice(-5000)
|
|
appendLog(cleanData(message), this.config.id, this.config.name, this.config.ip, 0)
|
|
})
|
|
|
|
this.client.on('error', (err) => {
|
|
if (resolvedOrRejected) return
|
|
resolvedOrRejected = true
|
|
console.error(`❌ Error station ${name}:`, err.message)
|
|
this.config.output += '\r\n' + err.message + '\r\n'
|
|
resolve()
|
|
})
|
|
|
|
this.client.on('close', async () => {
|
|
console.log(`[${Date.now()}] 🔌 station ${name} disconnected`)
|
|
this.config.status = 'disconnected'
|
|
})
|
|
|
|
this.client.on('timeout', () => {
|
|
if (resolvedOrRejected) return
|
|
resolvedOrRejected = true
|
|
const message = '\r\nConnection timeout!!\r\n'
|
|
this.config.output += message
|
|
console.log(`⏳ Connection timeout station ${name}`)
|
|
this.client.destroy()
|
|
resolve()
|
|
// reject(new Error('Connection timeout'))
|
|
})
|
|
})
|
|
}
|
|
|
|
private sleep(ms: number) {
|
|
return new Promise((resolve) => setTimeout(resolve, ms))
|
|
}
|
|
|
|
async writeCommand(cmd: string | Buffer<ArrayBuffer>) {
|
|
if (this.client.destroyed) {
|
|
console.log(`⚠️ Cannot send, station ${this.config.name} is closed`)
|
|
return
|
|
}
|
|
this.client.write(cmd)
|
|
}
|
|
|
|
async disconnect() {
|
|
try {
|
|
console.log('[DISCONNECT] station', this.config.name)
|
|
this.client.destroy()
|
|
this.config.status = 'disconnected'
|
|
console.log(`🔻 Closed connection to station ${this.config.name}`)
|
|
} catch (e) {
|
|
console.error('Error closing line:', e)
|
|
}
|
|
}
|
|
|
|
public async reconnect(): Promise<boolean> {
|
|
try {
|
|
this.disconnect()
|
|
this.client = new net.Socket()
|
|
await this.sleep(1000)
|
|
await this.connect()
|
|
return true
|
|
} catch (err: any) {
|
|
return false
|
|
}
|
|
}
|
|
}
|