diff --git a/CMakeLists.txt b/CMakeLists.txt index b342e1d..62a8c35 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required (VERSION 3.7) project(core - VERSION 0.2.4 + VERSION 0.2.5 LANGUAGES C) add_executable(core src/main.c) diff --git a/src/handlers/http.c b/src/handlers/http.c index 5a3fbf3..7766d3f 100644 --- a/src/handlers/http.c +++ b/src/handlers/http.c @@ -90,6 +90,7 @@ handle_http_request(struct mg_connection *nc, struct http_message *hm) /* Normalize path - resolve "." and ".." (in-place). */ if (!mg_normalize_uri_path(&hm->uri, &hm->uri)) { mg_http_send_error(nc, 400, global_config.http_server_opts.extra_headers); + LOGGER_DEBUG("failed to normalize uri %.*s\n", hm->uri.len, hm->uri.p); return; } char *request_file_org = malloc(sizeof(char) * hm->uri.len); @@ -112,10 +113,12 @@ handle_http_request(struct mg_connection *nc, struct http_message *hm) { response.status_code = 0; mg_serve_http(nc, hm, global_config.http_server_opts); + LOGGER_DEBUG("serving %.*s\n", hm->uri.len, hm->uri.p); return; } else { + LOGGER_DEBUG("serving 'not found'\n"); endpoint = router_get_not_found_endpoint(); } } @@ -142,10 +145,13 @@ handle_http_request(struct mg_connection *nc, struct http_message *hm) } else { + LOGGER_DEBUG("calling endpoint function %p\n", endpoint->func); endpoint->func(nc, hm, endpoint->args, &response); + LOGGER_DEBUG("sending response to %p\n", nc); send_response(nc, &response); } + LOGGER_DEBUG("freeing endpoint args\n"); for(int i = 0; i < endpoint->args_count; ++i) { if(endpoint->args[i].type == ENDPOINT_ARG_TYPE_STR) @@ -169,6 +175,7 @@ handler_http(struct mg_connection *nc, int ev, void *p) } if(ev == MG_EV_HTTP_REQUEST) { + LOGGER_DEBUG("new http request (%p)\n", nc); struct http_message *hm = (struct http_message*)p; handle_http_request(nc, hm); } diff --git a/src/status.c b/src/status.c index 2008861..ee08c09 100644 --- a/src/status.c +++ b/src/status.c @@ -2,16 +2,21 @@ #include relay_t **global_relay_status_list; +char *relay_status_list_json_str; +size_t relay_status_list_json_str_len; void status_init() { global_relay_status_list = relay_get_all(); + relay_status_list_json_str = NULL; + relay_status_list_json_str_len = 0; } void status_reload_entry(int relay_id) { + LOGGER_DEBUG("reloading relay status\n"); relay_t **relays = global_relay_status_list; for(int i = 0; relays[i] != NULL; ++i) { @@ -25,12 +30,15 @@ status_reload_entry(int relay_id) relay_free(relays[i]); relays[i] = updated_relay; relays[i]->is_on = is_on_backup; + relay_status_list_json_str = NULL; + relay_status_list_json_str_len = 0; } } void status_update_entry(int relay_id, int is_on) { + LOGGER_DEBUG("updating relay status ([%d] = %d)\n", relay_id, is_on); relay_t **relays = global_relay_status_list; for(int i = 0; relays[i] != NULL; ++i) { @@ -39,32 +47,62 @@ status_update_entry(int relay_id, int is_on) continue; } relays[i]->is_on = is_on; + relay_status_list_json_str = NULL; + relay_status_list_json_str_len = 0; } } -static int is_websocket(const struct mg_connection *nc) +static int +is_websocket(const struct mg_connection *nc) { return nc->flags & MG_F_IS_WEBSOCKET; } +static void +validate_json_str_cache() +{ + if(!relay_status_list_json_str) + { + relay_t **relays = global_relay_status_list; + + cJSON *json = relay_list_to_json(relays); + + char *json_str = cJSON_Print(json); + size_t json_str_len = strlen(json_str); + + LOGGER_DEBUG("writing new json string to cache\n"); + relay_status_list_json_str = json_str; + relay_status_list_json_str_len = json_str_len; + + cJSON_Delete(json); + } + +} + + void status_broadcast(struct mg_mgr *mgr) { struct mg_connection *c; - relay_t **relays = global_relay_status_list; + validate_json_str_cache(); + + char *json_str = relay_status_list_json_str; + size_t json_str_len = relay_status_list_json_str_len; - cJSON *json = relay_list_to_json(relays); - char *json_str = cJSON_Print(json); - size_t json_str_len = strlen(json_str); + int c_count = 0; for (c = mg_next(mgr, NULL); c != NULL; c = mg_next(mgr, c)) { if(is_websocket(c)) { mg_send_websocket_frame(c, WEBSOCKET_OP_TEXT, json_str, json_str_len); + ++c_count; } } - free(json_str); - cJSON_Delete(json); + + if(c_count) + { + LOGGER_DEBUG("finished status broadcast to %d client(s)\n", c_count); + } } void @@ -75,20 +113,19 @@ status_send(struct mg_connection *c) return; } - relay_t **relays = global_relay_status_list; - - cJSON *json = relay_list_to_json(relays); - char *json_str = cJSON_Print(json); - size_t json_str_len = strlen(json_str); + validate_json_str_cache(); + + char *json_str = relay_status_list_json_str; + size_t json_str_len = relay_status_list_json_str_len; mg_send_websocket_frame(c, WEBSOCKET_OP_TEXT, json_str, json_str_len); - free(json_str); - cJSON_Delete(json); + LOGGER_DEBUG("finished status send\n"); } void status_free() { relay_free_list(global_relay_status_list); + free(relay_status_list_json_str); }