Add support for the --once option

This commit is contained in:
Shuanglei Tao
2016-10-10 21:39:43 +08:00
parent f3d06b2857
commit 3c9884a87b
5 changed files with 48 additions and 13 deletions

View File

@@ -65,6 +65,7 @@ OPTIONS:
--gid, -g Group id to run with
--signal, -s Signal to send to the command when exit it (default: SIGHUP)
--reconnect, -r Time to reconnect for the client in seconds (default: 10)
--once, -o Accept only one client and exit on disconnection
--ssl, -S Enable ssl
--ssl-cert, -C Ssl certificate file path
--ssl-key, -K Ssl key file path

30
src/index.html vendored
View File

@@ -600,20 +600,17 @@
var io = term.io.push();
io.onVTKeystroke = function(str) {
if (ws.readyState === WebSocket.OPEN) {
ws.send("0" + str);
}
};
io.sendString = io.onVTKeystroke;
io.onTerminalResize = function(columns, rows) {
ws.send(
"2" + JSON.stringify(
{
columns: columns,
rows: rows,
if (ws.readyState === WebSocket.OPEN) {
ws.send("2" + JSON.stringify({columns: columns, rows: rows}));
}
)
)
};
term.installKeyboard();
@@ -635,7 +632,7 @@
term.setWindowTitle(data);
break;
case '3':
preferences = JSON.parse(data);
var preferences = JSON.parse(data);
Object.keys(preferences).forEach(function(key) {
console.log("Setting " + key + ": " + preferences[key]);
term.getPrefs().set(key, preferences[key]);
@@ -651,13 +648,30 @@
ws.onclose = function(event) {
if (term) {
term.uninstallKeyboard();
setTimeout(function(){
term.io.showOverlay("Connection Closed", null);
}, 300);
}
clearInterval(pingTimer);
if (autoReconnect > 0) {
setTimeout(openWs, autoReconnect * 1000);
}
};
ws.onerror = function(event) {
var errorNode = document.createElement('div');
errorNode.style.cssText = [
"color: red",
"font-size: x-large",
"opacity: 0.75",
"text-align: center",
"margin: 1em",
"padding: 0.2em",
"border: 0.1em dotted #ccc"
].join(";");
errorNode.textContent = "Websocket handshake failed!";
document.getElementById("terminal").appendChild(errorNode);
};
};

View File

@@ -65,7 +65,7 @@ parse_window_size(const char *json) {
void
tty_client_destroy(struct tty_client *client) {
if (client->exit)
if (client->exit || client->pid <= 0)
return;
// stop event loop
@@ -159,6 +159,12 @@ callback_tty(struct lws *wsi, enum lws_callback_reasons reason,
struct winsize *size;
switch (reason) {
case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION:
if (server->once && server->client_count > 0) {
lwsl_notice("refuse to serve new client due to the --once option.\n");
return -1;
}
break;
case LWS_CALLBACK_ESTABLISHED:
client->exit = false;
client->initialized = false;
@@ -305,6 +311,12 @@ callback_tty(struct lws *wsi, enum lws_callback_reasons reason,
case LWS_CALLBACK_CLOSED:
tty_client_destroy(client);
lwsl_notice("client disconnected from %s (%s), total: %d\n", client->hostname, client->address, server->client_count);
if (server->once && server->client_count == 0) {
lwsl_notice("exiting due to the --once option.\n");
force_exit = true;
lws_cancel_service(context);
exit(0);
}
break;
default:

View File

@@ -33,12 +33,13 @@ static const struct option options[] = {
{"ssl-cert", required_argument, NULL, 'C'},
{"ssl-key", required_argument, NULL, 'K'},
{"ssl-ca", required_argument, NULL, 'A'},
{"once", no_argument, NULL, 'o'},
{"debug", required_argument, NULL, 'd'},
{"version", no_argument, NULL, 'v'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, 0, 0}
};
static const char *opt_string = "p:i:c:u:g:s:r:aSC:K:A:d:vh";
static const char *opt_string = "p:i:c:u:g:s:r:aSC:K:A:od:vh";
void print_help() {
fprintf(stderr, "ttyd is a tool for sharing terminal over the web\n\n"
@@ -54,6 +55,7 @@ void print_help() {
" --gid, -g Group id to run with\n"
" --signal, -s Signal to send to the command when exit it (default: SIGHUP)\n"
" --reconnect, -r Time to reconnect for the client in seconds (default: 10)\n"
" --once, -o Accept only one client and exit on disconnection\n"
" --ssl, -S Enable ssl\n"
" --ssl-cert, -C Ssl certificate file path\n"
" --ssl-key, -K Ssl key file path\n"
@@ -200,6 +202,9 @@ main(int argc, char **argv) {
case 'd':
debug_level = atoi(optarg);
break;
case 'o':
server->once = true;
break;
case 'p':
info.port = atoi(optarg);
if (info.port < 0) {
@@ -317,6 +322,8 @@ main(int argc, char **argv) {
lwsl_notice(" start command: %s\n", server->command);
lwsl_notice(" reconnect timeout: %ds\n", server->reconnect);
lwsl_notice(" close signal: %s (%d)\n", server->sig_name, server->sig_code);
if (server->once)
lwsl_notice(" once: true\n");
// libwebsockets main loop
while (!force_exit) {

View File

@@ -71,6 +71,7 @@ struct tty_server {
char **argv; // command with arguments
int sig_code; // close signal
char *sig_name; // human readable signal string
bool once; // whether accept only one client and exit on disconnection
pthread_mutex_t lock;
};