У меня есть программа TUI (текстовый интерфейс пользователя), которую я хотел бы обслуживать по сетевому соединению. Образец со страницы входа в систему (который сейчас мало что делает) размещен ниже. Я использую tui-go для своей библиотеки TUI.
program.go
package main
import (
"log"
"github.com/marcusolsson/tui-go"
)
var logo string = "My Logo"
func main() {
Login()
}
func Login() {
inUser := tui.NewEntry()
inUser.SetFocused(true)
inPass := tui.NewEntry()
inPass.SetEchoMode(tui.EchoModePassword)
form := tui.NewGrid(0, 0)
form.AppendRow(tui.NewLabel("Username"), tui.NewLabel("Password"))
form.AppendRow(inUser, inPass)
// TODO: create OnActivated function
btnLogin := tui.NewButton("[Login]")
// TODO: create OnActivated function
btnRegister := tui.NewButton("[Register]")
buttons := tui.NewHBox(
tui.NewSpacer(),
tui.NewPadder(1, 0, btnLogin),
tui.NewPadder(1, 0, btnRegister),
)
window := tui.NewVBox(
tui.NewPadder(1, 1, form),
buttons,
)
window.SetBorder(true)
root := tui.NewVBox(
tui.NewSpacer(),
window,
tui.NewSpacer(),
)
tui.DefaultFocusChain.Set(inUser, inPass, btnLogin, btnRegister)
ui, err := tui.New(root)
if err != nil {
log.Fatal(err)
}
ui.SetKeybinding("Esc", func() { ui.Quit() })
if err := ui.Run(); err != nil {
log.Fatal(err)
}
}
Затем у меня есть другая программа для запуска двоичного файла program.go в pty и отправки его через сокет. В идеале я хотел бы, чтобы пользователь подключался с помощью множества методов, таких как telnet, ssh или netcat. Проблема в том, что когда я отправляю pty через сокет, он ведет себя не так, как если бы я просто запускал бинарный файл program.go из своей оболочки. Ниже приведена копия моей серверной программы. Я использую библиотеку pty для создания файла * os.File, который отправляется через сокет.
server.go
package main
import (
"net"
"log"
"io"
"os/exec"
"github.com/kr/pty"
)
func main() {
ln, err := net.Listen("tcp", ":2323")
if err != nil {
log.Fatal(err)
}
defer ln.Close()
for {
conn, err := ln.Accept()
if err != nil {
log.Fatal(err)
}
go startProg(conn)
}
}
func startProg(conn net.Conn) {
defer conn.Close()
term, err := pty.StartWithSize(
exec.Command("./program"),
&pty.Winsize{Cols: 100, Rows: 30},
)
if err != nil {
log.Fatal(err)
}
defer term.Close()
go io.Copy(term, conn)
io.Copy(conn, term)
}
Есть ли способ заставить работать TUI так, как если бы он нормально работал из оболочки? Кроме того, как мне прочитать данные, которые пользователь вводит в TUI? Потому что при попытке чтения как из соединения, так и из * os.File, возвращаемого pty, я не могу получить никаких данных вообще.
Любая помощь очень ценится!