void* thread_func(void* arg) { int socket_desc = (int) arg, proc_id, flag = 0; float left, right, result; char operation, message[100]; Calculation msg = CALCULATION__INIT; Result res = RESULT__INIT; uint8_t calc_buf[1024], result_buf[1024]; ssize_t len, result_len; len = recv(socket_desc, calc_buf, 1024, 0); deserialize_input(&msg, len, calc_buf, &left, &right, &operation, &proc_id); add_to_online(proc_id); while ((len = recv(socket_desc, calc_buf, 1024, 0))) { deserialize_input(&msg, len, calc_buf, &left, &right, &operation, &proc_id); result = calculate(left, right, operation); serialize_result(result_buf, &res, result, &result_len); sprintf(message, "Client %d calculated %f %c %f = %f\n", proc_id, left, operation, right, result); write_to_shm(message); send(socket_desc, result_buf, result_len, 0); } sprintf(message, "Client %d has disconnected\n", proc_id); remove_from_online(proc_id); notify(0, proc_id); close(socket_desc); active_connections--; printf("Active connections are: %d\n", active_connections); return NULL; }
static void server_rpc_cb(struct evhttp_request *req, void *arg) { struct rpc_context *rpc_context = (struct rpc_context *)arg; char *json = read_req_buffer(req); if(!json) { evhttp_send_error(req, 500, "Internal server error"); return; } struct method_t *method = deserialize_method_call(json); if(!method) { evhttp_send_error(req, 500, "Error deserializing method call"); free(json); return; } void *satellite_data; rpc_method_impl_t impl = search_method_entry(rpc_context->lookup, method->name, &satellite_data); if(!impl) { evhttp_send_error(req, 500, "Method not found"); } else { //impl should also throw error char *err; struct data_t *result = impl(method->params, method->nparams, &err, satellite_data); char *json_result = NULL; struct evbuffer *evb = evbuffer_new(); if(result && (json_result = serialize_result(result, NULL)) && evb) { if(evbuffer_add(evb, json_result, strlen(json_result))) { evhttp_send_error(req, 500, "Internal server error"); } else { evhttp_send_reply(req, 200, "OK", evb); } } else { if(err) { evhttp_send_error(req, 500, err); free(err); } else { evhttp_send_error(req, 500, "Internal server error"); } } if(evb) evbuffer_free(evb); if(json_result) free(json_result); if(result) free_data_t(result); } free(json); free_method_t(method); }
int main() { { struct method_t m = {"test0", NULL, 0}; char *ser = serialize_method_call(&m); char *expected = "{\"method\":\"test0\",\"params\":[]}"; if(strcmp(ser, expected)) { printf("failed = actual:%s expected:%s\n", ser, expected); } free(ser); } json_int_t i = 1; struct data_t param1 = { RPC_INT, &i, NULL, 0}; { const struct data_t* param[] = { ¶m1 }; struct method_t m = {"test1", (struct data_t**)param, 1}; char *ser = serialize_method_call(&m); char *expected = "{\"method\":\"test1\",\"params\":[1]}"; if(strcmp(ser, expected)) { printf("failed = actual:%s expected:%s\n", ser, expected); } free(ser); } struct data_t param2 = { RPC_STRING, "searaft", NULL, 0}; { const struct data_t* param[] = { ¶m1, ¶m2 }; struct method_t m = {"test2",(struct data_t**)param, 2}; char *ser = serialize_method_call(&m); char *expected = "{\"method\":\"test2\",\"params\":[1,\"searaft\"]}"; if(strcmp(ser, expected)) { printf("failed = actual:%s expected:%s\n", ser, expected); } free(ser); } double d = 12.01; struct data_t param3 = { RPC_REAL, &d, NULL, 0}; { struct data_t *param4[] = { ¶m1, ¶m2 }; const struct data_t param5 = { RPC_VECTOR, NULL, param4, 2}; const struct data_t* param[] = { ¶m3, ¶m5 }; struct method_t m = {"test3",(struct data_t**)param, 2}; char *ser = serialize_method_call(&m); char *expected = "{\"method\":\"test3\",\"params\":[12.01,[1,\"searaft\"]]}"; if(strcmp(ser, expected)) { printf("failed = actual:%s expected:%s\n", ser, expected); } free(ser); } { char *error = NULL; struct data_t *data1 = deserialize_result("{\"result-type\": \"SUCCESS\", \"result\" : 1 }", &error); if(data1) { int val = *(json_int_t *)data1->value; if(val != 1) { printf("failed = actual:%d expected: 1\n", val); } free_data_t(data1); } else { printf("failed = actual: NULL expected: 1"); } } { char *error = NULL; struct data_t *data1 = deserialize_result("{\"result-type\": \"SUCCESS\", \"result\" : [1, \"searaft\"] }", &error); if(data1) { if(data1->type == RPC_VECTOR) { if(data1->length == 2) { if(data1->child[0]->type != RPC_INT || data1->child[1]->type != RPC_STRING || *(json_int_t *)data1->child[0]->value != 1 || strcmp((char *)data1->child[1]->value, "searaft")) { printf("failed = object value dont match\n"); } } else { printf("failed = actual: %d expected: 2\n", data1->length); } } else { printf("failed = actual: %d expected: %d\n", data1->type, RPC_VECTOR); } free_data_t(data1); } else { printf("failed = actual: NULL expected: 1"); } } { char *error = NULL; (void)deserialize_result("{\"result-type\": \"ERROR\", \"result\" : \"test error\"}", &error); if(error) { if(strcmp("test error", error)) { printf("failed = actual:%s expected: \"test error\"\n", error); } free(error); } else { printf("failed = actual: NULL expected: \"test error\""); } } { struct method_t *mtd = deserialize_method_call("{\"method\" : \"test\", \"params\" : [1, 2]}"); if(mtd && 0 == strcmp(mtd->name, "test")) { if(mtd->nparams == 2) { if(mtd->params[0]->type != RPC_INT || mtd->params[1]->type != RPC_INT || *(json_int_t *)mtd->params[0]->value != 1 || *(json_int_t *)mtd->params[1]->value != 2) { printf("failed = param value dont match\n"); } } else { printf("failed = actual:%d expected: 2\n", mtd->nparams); } } else { printf("failed = actual:%s expected: \"test\"\n", mtd->name); } } { json_int_t i = 42; struct data_t data1 = { RPC_INT, &i, NULL, 0}; char *ser = serialize_result(&data1, NULL); char *expected = "{\"result-type\":\"SUCCESS\",\"result\":42}"; if(strcmp(ser, expected)) { printf("failed = actual:%s expected:%s\n", ser, expected); } free(ser); } { char *ser = serialize_result(NULL, "test error"); char *expected = "{\"result-type\":\"ERROR\",\"result\":\"test error\"}"; if(strcmp(ser, expected)) { printf("failed = actual:%s expected:%s\n", ser, expected); } free(ser); } return 0; }