Skip to content

Commit

Permalink
Support auto reconnection
Browse files Browse the repository at this point in the history
A new option `--auto-reconnect` which takes seconds to reconnect is
added.
  • Loading branch information
yudai committed Aug 23, 2015
1 parent 4df9ac8 commit acacba6
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 56 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ By default, gotty starts a web server at port 8080. Open the URL on your web bro
--random-url, -r Add a random string to the URL [$GOTTY_RANDOM_URL]
--profile-file, -f "~/.gotty" Path to profile file [$GOTTY_PROFILE_FILE]
--title-format "GoTTY - {{ .Command }} ({{ .Hostname }})" Title format of browser window [$GOTTY_TITLE_FORMAT]
--version, -v print the version
--auto-reconnect "-1" Seconds to automatically reconnect to the server when the connection is closed (default: disabled) [$GOTTY_AUTO_RECONNECT]
```

By default, gotty doesn't allow clients to send any keystrokes or commands except terminal window resizing. When you want to permit clients to write input to the PTY, add the `-w` option. However, accepting input from remote clients is dangerous for most commands. Make sure that only trusted clients can connect to your gotty server when you activate this option. If you need interaction with the PTY, consider starting gotty with tmux or GNU Screen and run your main command on it.
Expand Down
17 changes: 9 additions & 8 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,15 @@ type App struct {
}

type Options struct {
Address string
Port string
PermitWrite bool
Credential string
RandomUrl bool
ProfileFile string
TitleFormat string
Command []string
Address string
Port string
PermitWrite bool
Credential string
RandomUrl bool
ProfileFile string
TitleFormat string
AutoReconnect int
Command []string
}

const DefaultProfileFilePath = "~/.gotty"
Expand Down
18 changes: 15 additions & 3 deletions app/client_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ const (
)

const (
Output = '0'
SetWindowTitle = '1'
SetPreferences = '2'
Output = '0'
SetWindowTitle = '1'
SetPreferences = '2'
SetAutoReconnect = '3'
)

type argResizeTerminal struct {
Expand Down Expand Up @@ -124,6 +125,17 @@ func (context *clientContext) sendInitialize() error {
writer.Write(prefs)
writer.Close()

if context.app.options.AutoReconnect >= 0 {
autoReconnect, _ := json.Marshal(context.app.options.AutoReconnect)
writer, err = context.connection.NextWriter(websocket.TextMessage)
if err != nil {
return err
}
writer.Write([]byte{SetAutoReconnect})
writer.Write(autoReconnect)
writer.Close()
}

return nil
}

Expand Down
4 changes: 2 additions & 2 deletions app/resource.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ func main() {
Usage: "Title format of browser window",
EnvVar: "GOTTY_TITLE_FORMAT",
},
cli.IntFlag{
Name: "auto-reconnect",
Value: -1,
Usage: "Seconds to automatically reconnect to the server when the connection is closed (default: disabled)",
EnvVar: "GOTTY_AUTO_RECONNECT",
},
}
cmd.Action = func(c *cli.Context) {
if len(c.Args()) == 0 {
Expand All @@ -72,6 +78,7 @@ func main() {
c.Bool("random-url"),
c.String("profile-file"),
c.String("title-format"),
c.Int("auto-reconnect"),
c.Args(),
},
)
Expand Down
106 changes: 64 additions & 42 deletions resources/gotty.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,62 +2,84 @@
var httpsEnabled = window.location.protocol == "https:";
var url = (httpsEnabled ? 'wss://' : 'ws://') + window.location.host + window.location.pathname + 'ws';
var protocols = ["gotty"];
var ws = new WebSocket(url, protocols);
var autoReconnect = -1;

var term;
var openWs = function() {
var ws = new WebSocket(url, protocols);

ws.onopen = function(event) {
hterm.defaultStorage = new lib.Storage.Local();
hterm.defaultStorage.clear();
var term;

term = new hterm.Terminal();
ws.onopen = function(event) {
hterm.defaultStorage = new lib.Storage.Local();
hterm.defaultStorage.clear();

term.onTerminalReady = function() {
var io = term.io.push();
term = new hterm.Terminal();

io.onVTKeystroke = function(str) {
ws.send("0" + str);
};
term.onTerminalReady = function() {
var io = term.io.push();

io.onVTKeystroke = function(str) {
ws.send("0" + str);
};

io.sendString = io.onVTKeystroke;
io.sendString = io.onVTKeystroke;

io.onTerminalResize = function(columns, rows) {
ws.send(
"1" + JSON.stringify(
{
columns: columns,
rows: rows,
}
io.onTerminalResize = function(columns, rows) {
ws.send(
"1" + JSON.stringify(
{
columns: columns,
rows: rows,
}
)
)
)
};

term.installKeyboard();
};

term.installKeyboard();
term.decorate(document.body);
};

term.decorate(document.body);
};

ws.onmessage = function(event) {
data = event.data.slice(1);
switch(event.data[0]) {
case '0':
term.io.writeUTF16(data);
break;
case '1':
term.setWindowTitle(data);
break;
case '2':
preferences = JSON.parse(data);
Object.keys(preferences).forEach(function(key) {
term.getPrefs().set(key, preferences[key]);
});
break;
ws.onmessage = function(event) {
data = event.data.slice(1);
switch(event.data[0]) {
case '0':
term.io.writeUTF16(data);
break;
case '1':
term.setWindowTitle(data);
break;
case '2':
preferences = JSON.parse(data);
Object.keys(preferences).forEach(function(key) {
term.getPrefs().set(key, preferences[key]);
});
break;
case '3':
autoReconnect = JSON.parse(data);
break;
}
}

ws.onclose = function(event) {
if (term) {
term.uninstallKeyboard();
term.io.showOverlay("Connection Closed", null);
}
tryReconnect();
}

ws.onerror = function(error) {
tryReconnect();
}
}

ws.onclose = function(event) {
term.io.showOverlay("Connection Closed", null);
term.uninstallKeyboard();
openWs();

var tryReconnect = function() {
if (autoReconnect >= 0) {
setTimeout(openWs, autoReconnect * 1000);
}
}
})()

0 comments on commit acacba6

Please sign in to comment.