diff options
Diffstat (limited to 'resource.c')
-rw-r--r-- | resource.c | 56 |
1 files changed, 42 insertions, 14 deletions
@@ -12,23 +12,17 @@ struct resource_object { static struct resource_object position_object; static struct resource_object signal_object; -static void resource_obj_send(struct client *c, struct resource_object *obj) +static void resource_obj_send_one(gpointer data, gpointer user_data) { - GString *string = obj->string; - - if (!string) - return; + GString *string = user_data; + struct client *c = data; respond_chunk(c, string); } -// Update this client with the new resource object data -static void resource_obj_update(gpointer data, gpointer user_data) +static void resource_obj_send_all(struct resource_object *obj, GString *str) { - struct resource_object *obj = user_data; - struct client *c = data; - - resource_obj_send(c, obj); + g_list_foreach(obj->client_list, resource_obj_send_one, str); } static void resource_obj_set_string(struct resource_object *obj, GString *str) @@ -39,7 +33,7 @@ static void resource_obj_set_string(struct resource_object *obj, GString *str) obj->string = str; g_string_free(old, TRUE); - g_list_foreach(obj->client_list, resource_obj_update, obj); + resource_obj_send_all(obj, str); } static void resource_obj_add_client(struct resource_object *obj, @@ -54,10 +48,23 @@ static void resource_obj_del_client(struct resource_object *obj, obj->client_list = g_list_remove(obj->client_list, c); } +static GString *object_backend_status(struct resource *r) +{ + GString *str; + + str = g_string_new("event: backend\n"); + g_string_append_printf(str, + "data: {\"status\":\"%s\",\"timestamp\":%ld}\n\n", + r->updater ? "connected" : "disconnected", + r->updater_time); + + return str; +} static int object_v1_get(struct client *c, struct resource *r) { struct resource_object *obj = r->data; + GString *str; respond_header(c, 200, "OK", "Cache-Control: no-cache\r\n" @@ -65,7 +72,13 @@ static int object_v1_get(struct client *c, struct resource *r) "Content-Type: text/event-stream; charset=UTF-8\r\n" "Transfer-Encoding: chunked\r\n"); - resource_obj_send(c, obj); + str = object_backend_status(r); + g_string_append(str, "retry: 10000\n"); + if (obj->string) + g_string_append_len(str, obj->string->str, + obj->string->len); + respond_chunk(c, str); + g_string_free(str, TRUE); // Add this client to the object list so it receives updates resource_obj_add_client(obj, c); @@ -83,8 +96,15 @@ static void object_v1_close(struct client *c, struct resource *r) static void object_v1_update_open(struct client *c, struct resource *r) { + GString *str; + // Keep track of the latest updater r->updater = c; + time(&r->updater_time); + + str = object_backend_status(r); + resource_obj_send_all(r->data, str); + g_string_free(str, TRUE); } // Update all attached clients with the new resource object data @@ -119,10 +139,18 @@ static int object_v1_update(struct client *c, struct resource *r, const char *m) static void object_v1_update_close(struct client *c, struct resource *r) { + GString *str; + // If the updater goes away, clear the data so we don't serve // stale data. - if (r->updater == c) + if (r->updater == c) { r->updater = NULL; + time(&r->updater_time); + + str = object_backend_status(r); + resource_obj_send_all(r->data, str); + g_string_free(str, TRUE); + } } static const struct resource_ops resource_v1_ops = { |