jsonrpc_server.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. * json rpc server
  3. *
  4. * @build make jsonrpc
  5. * @server bin/jsonrpc_server 1234
  6. * @client bin/jsonrpc_client 127.0.0.1 1234 add 1 2
  7. *
  8. */
  9. #include "hloop.h"
  10. #include "hbase.h"
  11. #include "hsocket.h"
  12. #include "jsonrpc.h"
  13. #include "cJSON.h"
  14. #include "router.h"
  15. #include "handler.h"
  16. // hloop_create_tcp_server -> on_accept -> hio_read -> on_recv -> hio_write
  17. static int verbose = 0;
  18. static unpack_setting_t jsonrpc_unpack_setting;
  19. jsonrpc_router router[] = {
  20. {"add", do_add},
  21. {"sub", do_sub},
  22. {"mul", do_mul},
  23. {"div", do_div},
  24. };
  25. #define JSONRPC_ROUTER_NUM (sizeof(router)/sizeof(router[0]))
  26. static void on_close(hio_t* io) {
  27. printf("on_close fd=%d error=%d\n", hio_fd(io), hio_error(io));
  28. }
  29. static void on_recv(hio_t* io, void* readbuf, int readbytes) {
  30. // printf("on_recv fd=%d readbytes=%d\n", hio_fd(io), readbytes);
  31. if (verbose) {
  32. char localaddrstr[SOCKADDR_STRLEN] = {0};
  33. char peeraddrstr[SOCKADDR_STRLEN] = {0};
  34. printf("[%s] <=> [%s]\n",
  35. SOCKADDR_STR(hio_localaddr(io), localaddrstr),
  36. SOCKADDR_STR(hio_peeraddr(io), peeraddrstr));
  37. }
  38. // unpack -> cJSON_Parse -> router -> cJSON_Print -> pack -> hio_write
  39. // unpack
  40. jsonrpc_message msg;
  41. memset(&msg, 0, sizeof(msg));
  42. int packlen = jsonrpc_unpack(&msg, readbuf, readbytes);
  43. if (packlen < 0) {
  44. printf("jsonrpc_unpack failed!\n");
  45. return;
  46. }
  47. assert(packlen == readbytes);
  48. // cJSON_Parse
  49. printf("> %.*s\n", msg.head.length, msg.body);
  50. cJSON* jreq = cJSON_ParseWithLength(msg.body, msg.head.length);
  51. cJSON* jres = cJSON_CreateObject();
  52. cJSON* jmethod = cJSON_GetObjectItem(jreq, "method");
  53. if (!jmethod || !cJSON_IsString(jmethod)) {
  54. bad_request(jreq, jres);
  55. } else {
  56. // router
  57. char* method = cJSON_GetStringValue(jmethod);
  58. bool found = false;
  59. for (int i = 0; i < JSONRPC_ROUTER_NUM; ++i) {
  60. if (strcmp(method, router[i].method) == 0) {
  61. found = true;
  62. router[i].handler(jreq, jres);
  63. break;
  64. }
  65. }
  66. if (!found) {
  67. not_found(jreq, jres);
  68. }
  69. }
  70. // cJSON_Print
  71. memset(&msg, 0, sizeof(msg));
  72. msg.body = cJSON_PrintUnformatted(jres);
  73. msg.head.length = strlen(msg.body);
  74. printf("< %.*s\n", msg.head.length, msg.body);
  75. // pack
  76. packlen = jsonrpc_package_length(&msg.head);
  77. unsigned char* writebuf = NULL;
  78. HV_ALLOC(writebuf, packlen);
  79. packlen = jsonrpc_pack(&msg, writebuf, packlen);
  80. if (packlen > 0) {
  81. hio_write(io, writebuf, packlen);
  82. }
  83. cJSON_Delete(jreq);
  84. cJSON_Delete(jres);
  85. cJSON_free((void*)msg.body);
  86. HV_FREE(writebuf);
  87. }
  88. static void on_accept(hio_t* io) {
  89. printf("on_accept connfd=%d\n", hio_fd(io));
  90. if (verbose) {
  91. char localaddrstr[SOCKADDR_STRLEN] = {0};
  92. char peeraddrstr[SOCKADDR_STRLEN] = {0};
  93. printf("accept connfd=%d [%s] <= [%s]\n", hio_fd(io),
  94. SOCKADDR_STR(hio_localaddr(io), localaddrstr),
  95. SOCKADDR_STR(hio_peeraddr(io), peeraddrstr));
  96. }
  97. hio_setcb_close(io, on_close);
  98. hio_setcb_read(io, on_recv);
  99. hio_set_unpack(io, &jsonrpc_unpack_setting);
  100. hio_read(io);
  101. }
  102. int main(int argc, char** argv) {
  103. if (argc < 2) {
  104. printf("Usage: %s port\n", argv[0]);
  105. return -10;
  106. }
  107. int port = atoi(argv[1]);
  108. // init jsonrpc_unpack_setting
  109. memset(&jsonrpc_unpack_setting, 0, sizeof(unpack_setting_t));
  110. jsonrpc_unpack_setting.mode = UNPACK_BY_LENGTH_FIELD;
  111. jsonrpc_unpack_setting.package_max_length = DEFAULT_PACKAGE_MAX_LENGTH;
  112. jsonrpc_unpack_setting.body_offset = JSONRPC_HEAD_LENGTH;
  113. jsonrpc_unpack_setting.length_field_offset = 1;
  114. jsonrpc_unpack_setting.length_field_bytes = 4;
  115. jsonrpc_unpack_setting.length_field_coding = ENCODE_BY_BIG_ENDIAN;
  116. hloop_t* loop = hloop_new(0);
  117. hio_t* listenio = hloop_create_tcp_server(loop, "0.0.0.0", port, on_accept);
  118. if (listenio == NULL) {
  119. return -20;
  120. }
  121. printf("listenfd=%d\n", hio_fd(listenio));
  122. hloop_run(loop);
  123. hloop_free(&loop);
  124. return 0;
  125. }