mirror of
https://github.com/Eugeny/tabby.git
synced 2025-06-09 14:00:03 +00:00
move createSession() into session
This commit is contained in:
parent
827345d899
commit
e17ba8c351
@ -1,7 +1,8 @@
|
|||||||
import stripAnsi from 'strip-ansi'
|
import stripAnsi from 'strip-ansi'
|
||||||
import { SerialPort } from 'serialport'
|
import SerialPort from 'serialport'
|
||||||
import { Logger, Profile } from 'tabby-core'
|
import { Logger, LogService, NotificationsService, Profile } from 'tabby-core'
|
||||||
import { Subject, Observable } from 'rxjs'
|
import { Subject, Observable } from 'rxjs'
|
||||||
|
import { Injector, NgZone } from '@angular/core'
|
||||||
import { BaseSession, StreamProcessingOptions, TerminalStreamProcessor } from 'tabby-terminal'
|
import { BaseSession, StreamProcessingOptions, TerminalStreamProcessor } from 'tabby-terminal'
|
||||||
|
|
||||||
export interface LoginScript {
|
export interface LoginScript {
|
||||||
@ -46,9 +47,16 @@ export class SerialSession extends BaseSession {
|
|||||||
get serviceMessage$ (): Observable<string> { return this.serviceMessage }
|
get serviceMessage$ (): Observable<string> { return this.serviceMessage }
|
||||||
private serviceMessage = new Subject<string>()
|
private serviceMessage = new Subject<string>()
|
||||||
private streamProcessor: TerminalStreamProcessor
|
private streamProcessor: TerminalStreamProcessor
|
||||||
|
private zone: NgZone
|
||||||
|
private notifications: NotificationsService
|
||||||
|
|
||||||
constructor (public profile: SerialProfile) {
|
constructor (injector: Injector, public profile: SerialProfile) {
|
||||||
super()
|
super()
|
||||||
|
|
||||||
|
this.logger = injector.get(LogService).create(`serial-${profile.options.port}`)
|
||||||
|
this.zone = injector.get(NgZone)
|
||||||
|
this.notifications = injector.get(NotificationsService)
|
||||||
|
|
||||||
this.scripts = profile.options.scripts ?? []
|
this.scripts = profile.options.scripts ?? []
|
||||||
this.streamProcessor = new TerminalStreamProcessor(profile.options)
|
this.streamProcessor = new TerminalStreamProcessor(profile.options)
|
||||||
this.streamProcessor.outputToSession$.subscribe(data => {
|
this.streamProcessor.outputToSession$.subscribe(data => {
|
||||||
@ -102,6 +110,46 @@ export class SerialSession extends BaseSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async start (): Promise<void> {
|
async start (): Promise<void> {
|
||||||
|
this.serial = new SerialPort(this.profile.options.port, {
|
||||||
|
autoOpen: false,
|
||||||
|
baudRate: parseInt(this.profile.options.baudrate as any),
|
||||||
|
dataBits: this.profile.options.databits ?? 8,
|
||||||
|
stopBits: this.profile.options.stopbits ?? 1,
|
||||||
|
parity: this.profile.options.parity ?? 'none',
|
||||||
|
rtscts: this.profile.options.rtscts ?? false,
|
||||||
|
xon: this.profile.options.xon ?? false,
|
||||||
|
xoff: this.profile.options.xoff ?? false,
|
||||||
|
xany: this.profile.options.xany ?? false,
|
||||||
|
})
|
||||||
|
let connected = false
|
||||||
|
await new Promise(async (resolve, reject) => {
|
||||||
|
this.serial.on('open', () => {
|
||||||
|
connected = true
|
||||||
|
this.zone.run(resolve)
|
||||||
|
})
|
||||||
|
this.serial.on('error', error => {
|
||||||
|
this.zone.run(() => {
|
||||||
|
if (connected) {
|
||||||
|
this.notifications.error(error.toString())
|
||||||
|
} else {
|
||||||
|
reject(error)
|
||||||
|
}
|
||||||
|
this.destroy()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
this.serial.on('close', () => {
|
||||||
|
this.emitServiceMessage('Port closed')
|
||||||
|
this.destroy()
|
||||||
|
})
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.serial.open()
|
||||||
|
} catch (e) {
|
||||||
|
this.notifications.error(e.message)
|
||||||
|
reject(e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
this.open = true
|
this.open = true
|
||||||
|
|
||||||
this.serial.on('readable', () => {
|
this.serial.on('readable', () => {
|
||||||
|
@ -5,7 +5,6 @@ import { Component, Injector } from '@angular/core'
|
|||||||
import { first } from 'rxjs/operators'
|
import { first } from 'rxjs/operators'
|
||||||
import { SelectorService } from 'tabby-core'
|
import { SelectorService } from 'tabby-core'
|
||||||
import { BaseTerminalTabComponent } from 'tabby-terminal'
|
import { BaseTerminalTabComponent } from 'tabby-terminal'
|
||||||
import { SerialService } from '../services/serial.service'
|
|
||||||
import { SerialSession, BAUD_RATES, SerialProfile } from '../api'
|
import { SerialSession, BAUD_RATES, SerialProfile } from '../api'
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
@ -19,7 +18,6 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
|
|||||||
profile?: SerialProfile
|
profile?: SerialProfile
|
||||||
session: SerialSession|null = null
|
session: SerialSession|null = null
|
||||||
serialPort: any
|
serialPort: any
|
||||||
private serialService: SerialService
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
|
// eslint-disable-next-line @typescript-eslint/no-useless-constructor
|
||||||
constructor (
|
constructor (
|
||||||
@ -27,7 +25,6 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
|
|||||||
private selector: SelectorService,
|
private selector: SelectorService,
|
||||||
) {
|
) {
|
||||||
super(injector)
|
super(injector)
|
||||||
this.serialService = injector.get(SerialService)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit () {
|
ngOnInit () {
|
||||||
@ -67,7 +64,7 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const session = this.serialService.createSession(this.profile)
|
const session = new SerialSession(this.injector, this.profile)
|
||||||
this.setSession(session)
|
this.setSession(session)
|
||||||
this.write(`Connecting to `)
|
this.write(`Connecting to `)
|
||||||
|
|
||||||
@ -81,7 +78,7 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
|
|||||||
spinner.start()
|
spinner.start()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.serialPort = await this.serialService.connectSession(this.session!)
|
await this.session!.start()
|
||||||
spinner.stop(true)
|
spinner.stop(true)
|
||||||
session.emitServiceMessage('Port opened')
|
session.emitServiceMessage('Port opened')
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -89,7 +86,6 @@ export class SerialTabComponent extends BaseTerminalTabComponent {
|
|||||||
this.write(colors.black.bgRed(' X ') + ' ' + colors.red(e.message) + '\r\n')
|
this.write(colors.black.bgRed(' X ') + ' ' + colors.red(e.message) + '\r\n')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
await this.session!.start()
|
|
||||||
this.session!.resize(this.size.columns, this.size.rows)
|
this.session!.resize(this.size.columns, this.size.rows)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ import slugify from 'slugify'
|
|||||||
import deepClone from 'clone-deep'
|
import deepClone from 'clone-deep'
|
||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { ProfileProvider, NewTabParameters, SelectorService } from 'tabby-core'
|
import { ProfileProvider, NewTabParameters, SelectorService } from 'tabby-core'
|
||||||
|
import { InputMode, NewlineMode } from 'tabby-terminal'
|
||||||
import { SerialProfileSettingsComponent } from './components/serialProfileSettings.component'
|
import { SerialProfileSettingsComponent } from './components/serialProfileSettings.component'
|
||||||
import { SerialTabComponent } from './components/serialTab.component'
|
import { SerialTabComponent } from './components/serialTab.component'
|
||||||
import { SerialService } from './services/serial.service'
|
import { SerialService } from './services/serial.service'
|
||||||
@ -34,10 +35,10 @@ export class SerialProfilesService extends ProfileProvider {
|
|||||||
xany: false,
|
xany: false,
|
||||||
xoff: false,
|
xoff: false,
|
||||||
xon: false,
|
xon: false,
|
||||||
inputMode: null,
|
inputMode: 'local-echo' as InputMode,
|
||||||
outputMode: null,
|
outputMode: null,
|
||||||
inputNewlines: null,
|
inputNewlines: null,
|
||||||
outputNewlines: null,
|
outputNewlines: 'crlf' as NewlineMode,
|
||||||
},
|
},
|
||||||
isBuiltin: true,
|
isBuiltin: true,
|
||||||
isTemplate: true,
|
isTemplate: true,
|
||||||
@ -50,6 +51,8 @@ export class SerialProfilesService extends ProfileProvider {
|
|||||||
isBuiltin: true,
|
isBuiltin: true,
|
||||||
options: {
|
options: {
|
||||||
port: p.name,
|
port: p.name,
|
||||||
|
inputMode: 'local-echo' as InputMode,
|
||||||
|
outputNewlines: 'crlf' as NewlineMode,
|
||||||
},
|
},
|
||||||
})),
|
})),
|
||||||
]
|
]
|
||||||
|
@ -1,17 +1,13 @@
|
|||||||
import { Injectable, NgZone } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import SerialPort from 'serialport'
|
import SerialPort from 'serialport'
|
||||||
import { LogService, NotificationsService, SelectorService, ProfilesService } from 'tabby-core'
|
import { ProfilesService } from 'tabby-core'
|
||||||
import { SerialSession, SerialPortInfo, BAUD_RATES, SerialProfile } from '../api'
|
import { SerialPortInfo, SerialProfile } from '../api'
|
||||||
import { SerialTabComponent } from '../components/serialTab.component'
|
import { SerialTabComponent } from '../components/serialTab.component'
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class SerialService {
|
export class SerialService {
|
||||||
private constructor (
|
private constructor (
|
||||||
private log: LogService,
|
|
||||||
private zone: NgZone,
|
|
||||||
private notifications: NotificationsService,
|
|
||||||
private profilesService: ProfilesService,
|
private profilesService: ProfilesService,
|
||||||
private selector: SelectorService,
|
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
async listPorts (): Promise<SerialPortInfo[]> {
|
async listPorts (): Promise<SerialPortInfo[]> {
|
||||||
@ -21,55 +17,6 @@ export class SerialService {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
createSession (profile: SerialProfile): SerialSession {
|
|
||||||
const session = new SerialSession(profile)
|
|
||||||
session.logger = this.log.create(`serial-${profile.options.port}`)
|
|
||||||
return session
|
|
||||||
}
|
|
||||||
|
|
||||||
async connectSession (session: SerialSession): Promise<SerialPort> {
|
|
||||||
const serial = new SerialPort(session.profile.options.port, {
|
|
||||||
autoOpen: false,
|
|
||||||
baudRate: parseInt(session.profile.options.baudrate as any),
|
|
||||||
dataBits: session.profile.options.databits,
|
|
||||||
stopBits: session.profile.options.stopbits,
|
|
||||||
parity: session.profile.options.parity,
|
|
||||||
rtscts: session.profile.options.rtscts,
|
|
||||||
xon: session.profile.options.xon,
|
|
||||||
xoff: session.profile.options.xoff,
|
|
||||||
xany: session.profile.options.xany,
|
|
||||||
})
|
|
||||||
session.serial = serial
|
|
||||||
let connected = false
|
|
||||||
await new Promise(async (resolve, reject) => {
|
|
||||||
serial.on('open', () => {
|
|
||||||
connected = true
|
|
||||||
this.zone.run(resolve)
|
|
||||||
})
|
|
||||||
serial.on('error', error => {
|
|
||||||
this.zone.run(() => {
|
|
||||||
if (connected) {
|
|
||||||
this.notifications.error(error.toString())
|
|
||||||
} else {
|
|
||||||
reject(error)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
serial.on('close', () => {
|
|
||||||
session.emitServiceMessage('Port closed')
|
|
||||||
session.destroy()
|
|
||||||
})
|
|
||||||
|
|
||||||
try {
|
|
||||||
serial.open()
|
|
||||||
} catch (e) {
|
|
||||||
this.notifications.error(e.message)
|
|
||||||
reject(e)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return serial
|
|
||||||
}
|
|
||||||
|
|
||||||
quickConnect (query: string): Promise<SerialTabComponent|null> {
|
quickConnect (query: string): Promise<SerialTabComponent|null> {
|
||||||
let path = query
|
let path = query
|
||||||
let baudrate = 115200
|
let baudrate = 115200
|
||||||
@ -95,11 +42,4 @@ export class SerialService {
|
|||||||
window.localStorage.lastSerialConnection = JSON.stringify(profile)
|
window.localStorage.lastSerialConnection = JSON.stringify(profile)
|
||||||
return this.profilesService.openNewTabForProfile(profile) as Promise<SerialTabComponent|null>
|
return this.profilesService.openNewTabForProfile(profile) as Promise<SerialTabComponent|null>
|
||||||
}
|
}
|
||||||
|
|
||||||
async connectFoundPort (port: SerialPortInfo): Promise<SerialTabComponent|null> {
|
|
||||||
const rate = await this.selector.show('Baud rate', BAUD_RATES.map(x => ({
|
|
||||||
name: x.toString(), result: x,
|
|
||||||
})))
|
|
||||||
return this.quickConnect(`${port.name}@${rate}`)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import stripAnsi from 'strip-ansi'
|
|||||||
import socksv5 from 'socksv5'
|
import socksv5 from 'socksv5'
|
||||||
import { Injector, NgZone } from '@angular/core'
|
import { Injector, NgZone } from '@angular/core'
|
||||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||||
import { ConfigService, FileProvidersService, HostAppService, Logger, NotificationsService, Platform, PlatformService, wrapPromise, PromptModalComponent, Profile } from 'tabby-core'
|
import { ConfigService, FileProvidersService, HostAppService, Logger, NotificationsService, Platform, PlatformService, wrapPromise, PromptModalComponent, Profile, LogService } from 'tabby-core'
|
||||||
import { BaseSession } from 'tabby-terminal'
|
import { BaseSession } from 'tabby-terminal'
|
||||||
import { Server, Socket, createServer, createConnection } from 'net'
|
import { Server, Socket, createServer, createConnection } from 'net'
|
||||||
import { Client, ClientChannel, SFTPWrapper } from 'ssh2'
|
import { Client, ClientChannel, SFTPWrapper } from 'ssh2'
|
||||||
@ -287,6 +287,8 @@ export class SSHSession extends BaseSession {
|
|||||||
public profile: SSHProfile,
|
public profile: SSHProfile,
|
||||||
) {
|
) {
|
||||||
super()
|
super()
|
||||||
|
this.logger = injector.get(LogService).create(`ssh-${profile.options.host}-${profile.options.port}`)
|
||||||
|
|
||||||
this.passwordStorage = injector.get(PasswordStorageService)
|
this.passwordStorage = injector.get(PasswordStorageService)
|
||||||
this.ngbModal = injector.get(NgbModal)
|
this.ngbModal = injector.get(NgbModal)
|
||||||
this.hostApp = injector.get(HostAppService)
|
this.hostApp = injector.get(HostAppService)
|
||||||
|
@ -90,7 +90,7 @@ export class SSHTabComponent extends BaseTerminalTabComponent {
|
|||||||
throw new Error(`${session.profile.options.host}: jump host "${session.profile.options.jumpHost}" not found in your config`)
|
throw new Error(`${session.profile.options.host}: jump host "${session.profile.options.jumpHost}" not found in your config`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const jumpSession = this.ssh.createSession(jumpConnection)
|
const jumpSession = new SSHSession(this.injector, jumpConnection)
|
||||||
|
|
||||||
await this.setupOneSession(jumpSession)
|
await this.setupOneSession(jumpSession)
|
||||||
|
|
||||||
@ -173,7 +173,7 @@ export class SSHTabComponent extends BaseTerminalTabComponent {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const session = this.ssh.createSession(this.profile)
|
const session = new SSHSession(this.injector, this.profile)
|
||||||
this.setSession(session)
|
this.setSession(session)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -32,12 +32,6 @@ export class SSHService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
createSession (profile: SSHProfile): SSHSession {
|
|
||||||
const session = new SSHSession(this.injector, profile)
|
|
||||||
session.logger = this.log.create(`ssh-${profile.options.host}-${profile.options.port}`)
|
|
||||||
return session
|
|
||||||
}
|
|
||||||
|
|
||||||
async connectSession (session: SSHSession): Promise<void> {
|
async connectSession (session: SSHSession): Promise<void> {
|
||||||
const log = (s: any) => session.emitServiceMessage(s)
|
const log = (s: any) => session.emitServiceMessage(s)
|
||||||
|
|
||||||
|
@ -87,8 +87,10 @@ export class TerminalStreamProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
resize (): void {
|
resize (): void {
|
||||||
|
if (this.options.inputMode?.startsWith('readline')) {
|
||||||
this.inputReadlineOutStream.emit('resize')
|
this.inputReadlineOutStream.emit('resize')
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
close (): void {
|
close (): void {
|
||||||
this.inputReadline.close()
|
this.inputReadline.close()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user