Introduce wayvncctl startup amd shutdown events

Signed-off-by: Jim Ramsay <i.am@jimramsay.com>
pull/187/head
Jim Ramsay 2022-11-18 21:45:28 -05:00 committed by Andri Yngvason
parent 325b45ef49
commit fe10e46e29
3 changed files with 75 additions and 16 deletions

View File

@ -3,7 +3,7 @@
WAYVNCCTL=${WAYVNCCTL:-wayvncctl} WAYVNCCTL=${WAYVNCCTL:-wayvncctl}
connection_count_now() { connection_count_now() {
echo "Total clients: $count" echo "Total clients: $1"
} }
while IFS= read -r EVT; do while IFS= read -r EVT; do
@ -12,5 +12,13 @@ while IFS= read -r EVT; do
count=$(jq -r '.params.connection_count' <<<"$EVT") count=$(jq -r '.params.connection_count' <<<"$EVT")
connection_count_now "$count" connection_count_now "$count"
;; ;;
wayvnc-shutdown)
echo "wayvncctl is no longer running"
connection_count_now 0
;;
wayvnc-startup)
echo "Ready to receive wayvnc events"
;;
esac esac
done < <("$WAYVNCCTL" --wait --reconnect --json event-receive) done < <("$WAYVNCCTL" --wait --reconnect --json event-receive)

View File

@ -45,9 +45,13 @@ static bool do_debug = false;
if (do_debug) \ if (do_debug) \
LOG("DEBUG", fmt, ##__VA_ARGS__) LOG("DEBUG", fmt, ##__VA_ARGS__)
const char* EVT_LOCAL_SHUTDOWN = "wayvnc-shutdown";
const char* EVT_LOCAL_STARTUP = "wayvnc-startup";
struct ctl_client { struct ctl_client {
void* userdata; void* userdata;
struct sockaddr_un addr; struct sockaddr_un addr;
unsigned flags;
char read_buffer[512]; char read_buffer[512];
size_t read_len; size_t read_len;
@ -408,12 +412,11 @@ static void print_compact_json(json_t* data)
static int ctl_client_print_response(struct ctl_client* self, static int ctl_client_print_response(struct ctl_client* self,
struct jsonipc_request* request, struct jsonipc_request* request,
struct jsonipc_response* response, struct jsonipc_response* response)
unsigned flags)
{ {
DEBUG("Response code: %d", response->code); DEBUG("Response code: %d", response->code);
if (response->data) { if (response->data) {
if (flags & PRINT_JSON) if (self->flags & PRINT_JSON)
print_compact_json(response->data); print_compact_json(response->data);
else if (response->code == 0) else if (response->code == 0)
pretty_print(response->data, request); pretty_print(response->data, request);
@ -534,11 +537,32 @@ static void print_event(struct jsonipc_request* event, unsigned flags)
print_compact_json(event->json); print_compact_json(event->json);
} else { } else {
printf("\n%s:", event->method); printf("\n%s:", event->method);
print_as_yaml(event->params, 1, true); if (event->params)
print_as_yaml(event->params, 1, true);
else
printf("<<null>\n");
} }
fflush(stdout); fflush(stdout);
} }
static void send_local_event(struct ctl_client* self, const char* name)
{
struct jsonipc_request* event = jsonipc_event_new(name, NULL);
event->json = jsonipc_request_pack(event, NULL);
print_event(event, self->flags);
jsonipc_request_destroy(event);
}
static void send_startup_event(struct ctl_client* self)
{
send_local_event(self, EVT_LOCAL_STARTUP);
}
static void send_shutdown_event(struct ctl_client* self)
{
send_local_event(self, EVT_LOCAL_SHUTDOWN);
}
static ssize_t ctl_client_send_request(struct ctl_client* self, static ssize_t ctl_client_send_request(struct ctl_client* self,
struct jsonipc_request* request) struct jsonipc_request* request)
{ {
@ -573,6 +597,8 @@ static int ctl_client_register_for_events(struct ctl_client* self,
int result = response->code; int result = response->code;
jsonipc_response_destroy(response); jsonipc_response_destroy(response);
if (result == 0)
send_startup_event(self);
return result; return result;
} }
@ -585,7 +611,7 @@ static int ctl_client_reconnect_event_loop(struct ctl_client* self,
} }
static int ctl_client_event_loop(struct ctl_client* self, static int ctl_client_event_loop(struct ctl_client* self,
struct jsonipc_request* request, unsigned flags) struct jsonipc_request* request)
{ {
int result = ctl_client_register_for_events(self, request); int result = ctl_client_register_for_events(self, request);
if (result != 0) if (result != 0)
@ -597,29 +623,32 @@ static int ctl_client_event_loop(struct ctl_client* self,
DEBUG("Waiting for an event"); DEBUG("Waiting for an event");
json_t* root = read_one_object(self, -1); json_t* root = read_one_object(self, -1);
if (!root) { if (!root) {
if (errno == ECONNRESET && flags & RECONNECT && if (errno == ECONNRESET) {
ctl_client_reconnect_event_loop(self, send_shutdown_event(self);
request, -1) == 0) if (self->flags & RECONNECT &&
continue; ctl_client_reconnect_event_loop(
self, request, -1) == 0)
continue;
}
break; break;
} }
struct jsonipc_error err = JSONIPC_ERR_INIT; struct jsonipc_error err = JSONIPC_ERR_INIT;
struct jsonipc_request* event = jsonipc_event_parse_new(root, &err); struct jsonipc_request* event = jsonipc_event_parse_new(root, &err);
json_decref(root); json_decref(root);
print_event(event, flags); print_event(event, self->flags);
jsonipc_request_destroy(event); jsonipc_request_destroy(event);
} }
return 0; return 0;
} }
static int ctl_client_print_single_command(struct ctl_client* self, static int ctl_client_print_single_command(struct ctl_client* self,
struct jsonipc_request* request, unsigned flags) struct jsonipc_request* request)
{ {
struct jsonipc_response* response = ctl_client_run_single_command(self, struct jsonipc_response* response = ctl_client_run_single_command(self,
request); request);
if (!response) if (!response)
return 1; return 1;
int result = ctl_client_print_response(self, request, response, flags); int result = ctl_client_print_response(self, request, response);
jsonipc_response_destroy(response); jsonipc_response_destroy(response);
return result; return result;
} }
@ -627,6 +656,7 @@ static int ctl_client_print_single_command(struct ctl_client* self,
int ctl_client_run_command(struct ctl_client* self, int ctl_client_run_command(struct ctl_client* self,
int argc, char* argv[], unsigned flags) int argc, char* argv[], unsigned flags)
{ {
self->flags = flags;
int result = 1; int result = 1;
struct jsonipc_request* request = ctl_client_parse_args(self, argc, struct jsonipc_request* request = ctl_client_parse_args(self, argc,
argv); argv);
@ -634,9 +664,9 @@ int ctl_client_run_command(struct ctl_client* self,
goto parse_failure; goto parse_failure;
if (strcmp(request->method, "event-receive") == 0) if (strcmp(request->method, "event-receive") == 0)
result = ctl_client_event_loop(self, request, flags); result = ctl_client_event_loop(self, request);
else else
result = ctl_client_print_single_command(self, request, flags); result = ctl_client_print_single_command(self, request);
jsonipc_request_destroy(request); jsonipc_request_destroy(request);
parse_failure: parse_failure:

View File

@ -85,6 +85,24 @@ client-disconnected:
``` ```
## SPECIAL LOCAL EVENT TYPES
Especially useful when using _--wait_ or _--reconnect_ mode, wayvncctl will
generate 2 additional events not documented in *wayvnc(1)*:
*wayvnc-startup*
Sent when a successful wayvnc control connection is established and
event registration has succeeded, both upon initial startup and on
subsequent registrations with _--reconnect_.
No paramerers.
*wayvnc-shutdown*
Sent when the wayvnc control connection is dropped, usually due to
wayvnc exiting.
No paramerers.
# EXAMPLES # EXAMPLES
Query the server for all available IPC command names: Query the server for all available IPC command names:
@ -136,7 +154,7 @@ A script that takes an action for each client connect and disconnect event:
#!/bin/bash #!/bin/bash
connection_count_now() { connection_count_now() {
echo "Total clients: $count" echo "Total clients: $1"
} }
while IFS= read -r EVT; do while IFS= read -r EVT; do
@ -145,6 +163,9 @@ while IFS= read -r EVT; do
count=$(jq -r '.params.connection_count' <<<"$EVT") count=$(jq -r '.params.connection_count' <<<"$EVT")
connection_count_now "$count" connection_count_now "$count"
;; ;;
wayvnc-shutdown)
connection_count_now 0
;;
esac esac
done < <(wayvncctl --wait --reconnect --json event-receive) done < <(wayvncctl --wait --reconnect --json event-receive)
``` ```