diff --git a/client.go b/client.go index c2fce48..2417a6d 100644 --- a/client.go +++ b/client.go @@ -125,6 +125,8 @@ func (c *ttyShareClient) Run() (err error) { defer term.RestoreTerminal(os.Stdin.Fd(), state) clearScreen() + protoWS := server.NewTTYProtocolWS(c.wsConn) + monitorWinChanges := func() { // start monitoring the size of the terminal signal.Notify(c.wcChan, syscall.SIGWINCH) @@ -132,15 +134,13 @@ func (c *ttyShareClient) Run() (err error) { for { select { case <-c.wcChan: - log.Debugf("Detected new win size") c.updateThisWinSize() c.updateAndDecideStdoutMuted() + protoWS.SetWinSize(int(c.winSizes.thisW), int(c.winSizes.thisH)) } } } - protoWS := server.NewTTYProtocolWS(c.wsConn) - readLoop := func() { var err error diff --git a/main.go b/main.go index 873f558..932d347 100644 --- a/main.go +++ b/main.go @@ -16,11 +16,11 @@ import ( var version string = "0.0.0" -func createServer(frontListenAddress string, frontendPath string, tty io.Writer, sessionID string) *server.TTYServer { +func createServer(frontListenAddress string, frontendPath string, pty server.PTYHandler, sessionID string) *server.TTYServer { config := ttyServer.TTYServerConfig{ FrontListenAddress: frontListenAddress, FrontendPath: frontendPath, - TTYWriter: tty, + PTY: pty, SessionID: sessionID, } @@ -28,13 +28,16 @@ func createServer(frontListenAddress string, frontendPath string, tty io.Writer, return server } -type nilWriter struct { +type nilPTY struct { } -func (nw *nilWriter) Write(data []byte) (int, error) { +func (nw *nilPTY) Write(data []byte) (int, error) { return len(data), nil } +func (nw *nilPTY) Refresh() { +} + func main() { usageString := ` Usage: @@ -145,12 +148,12 @@ Flags: ptyMaster := ptyMasterNew() ptyMaster.Start(*commandName, strings.Fields(*commandArgs)) - var writer io.Writer = ptyMaster + var pty server.PTYHandler = ptyMaster if *readOnly { - writer = &nilWriter{} + pty = &nilPTY{} } - server := createServer(*listenAddress, *frontendPath, writer, sessionID) + server := createServer(*listenAddress, *frontendPath, pty, sessionID) if cols, rows, e := ptyMaster.GetWinSize(); e == nil { server.WindowSize(cols, rows) } @@ -163,9 +166,7 @@ Flags: mw := io.MultiWriter(os.Stdout, server) go func() { - err := server.Run(func(clientAddr string) { - ptyMaster.Refresh() - }) + err := server.Run() if err != nil { log.Debugf("Server done: %s", err.Error()) } diff --git a/server/server.go b/server/server.go index 51d87bf..8fe411b 100644 --- a/server/server.go +++ b/server/server.go @@ -3,9 +3,7 @@ package server import ( "fmt" "html/template" - "io" "mime" - "net/http" "os" "path/filepath" @@ -20,7 +18,10 @@ const ( errorNotAllowed = iota ) -type NewClientConnectedCB func(string) +type PTYHandler interface { + Write(data []byte) (int, error) + Refresh() +} // SessionTemplateModel used for templating type AASessionTemplateModel struct { @@ -33,16 +34,15 @@ type AASessionTemplateModel struct { type TTYServerConfig struct { FrontListenAddress string FrontendPath string - TTYWriter io.Writer + PTY PTYHandler SessionID string } // TTYServer represents the instance of a tty server type TTYServer struct { - httpServer *http.Server - newClientCB NewClientConnectedCB - config TTYServerConfig - session *ttyShareSession + httpServer *http.Server + config TTYServerConfig + session *ttyShareSession } func (server *TTYServer) serveContent(w http.ResponseWriter, r *http.Request, name string) { @@ -95,12 +95,12 @@ func NewTTYServer(config TTYServerConfig) (server *TTYServer) { }))) routesHandler.HandleFunc(fmt.Sprintf("/s/%s/", session), func(w http.ResponseWriter, r *http.Request) { - wsPath := "/s/" + session + "/ws" + wsPath := "/s/" + session + "/ws" pathPrefix := "/s/" + session // Check the frontend/templates/tty-share.in.html file to see where the template applies templateModel := struct { PathPrefix string - WSPath string + WSPath string }{pathPrefix, wsPath} // TODO Extract these in constants @@ -113,7 +113,7 @@ func NewTTYServer(config TTYServerConfig) (server *TTYServer) { server.handleWebsocket(w, r) }) routesHandler.NotFoundHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - templateModel := struct{PathPrefix string }{session} + templateModel := struct{ PathPrefix string }{session} server.handleWithTemplateHtml(w, r, "404.in.html", templateModel) }) } @@ -124,7 +124,7 @@ func NewTTYServer(config TTYServerConfig) (server *TTYServer) { installHandlers(config.SessionID) server.httpServer.Handler = routesHandler - server.session = newTTYShareSession(config.TTYWriter) + server.session = newTTYShareSession(config.PTY) return server } @@ -146,7 +146,8 @@ func (server *TTYServer) handleWebsocket(w http.ResponseWriter, r *http.Request) return } - server.newClientCB(conn.RemoteAddr().String()) + // On a new connection, ask for a refresh/redraw of the terminal app + server.config.PTY.Refresh() server.session.HandleWSConnection(conn) } @@ -174,8 +175,7 @@ func (server *TTYServer) handleWithTemplateHtml(responseWriter http.ResponseWrit } -func (server *TTYServer) Run(cb NewClientConnectedCB) (err error) { - server.newClientCB = cb +func (server *TTYServer) Run() (err error) { err = server.httpServer.ListenAndServe() log.Debug("Server finished") return diff --git a/server/session.go b/server/session.go index d66282d..2820962 100644 --- a/server/session.go +++ b/server/session.go @@ -14,7 +14,7 @@ type ttyShareSession struct { ttyProtoConnections *list.List isAlive bool lastWindowSizeMsg MsgTTYWinSize - ttyWriter io.Writer + ptyHandler PTYHandler } // quick and dirty locked writer @@ -37,11 +37,11 @@ func copyList(l *list.List) *list.List { return newList } -func newTTYShareSession(ttyWriter io.Writer) *ttyShareSession { +func newTTYShareSession(ptyHandler PTYHandler) *ttyShareSession { ttyShareSession := &ttyShareSession{ ttyProtoConnections: list.New(), - ttyWriter: ttyWriter, + ptyHandler: ptyHandler, } return ttyShareSession @@ -104,10 +104,10 @@ func (session *ttyShareSession) HandleWSConnection(wsConn *websocket.Conn) { for { err := protoConn.ReadAndHandle( func(data []byte) { - session.ttyWriter.Write(data) + session.ptyHandler.Write(data) }, func(cols, rows int) { - // Maybe ask the server side to refresh/repaint the tty window? + session.ptyHandler.Refresh() }, )