Posted By

my-classes on 04/26/14


Tagged

http webserver Zmq ZeroMQ NanoMSG


Versions (?)

My-Classes.com: Combining ZeroMQ and NanoMsg for Serving Web-requests


 / Published in: C++
 

URL: http://my-classes.com/2014/04/26/combining-zeromq-and-nanomsg-for-serving-web-requests/

A pretty simple example, that always replies 'Hello World!!' to the browser. The raw ROUTER socket is listening on tcp port 8080, so any browser that sends a request on port 8080 of localhost, will get back the response. The internal NanoMsg communication is happening on inproc channel. A dedicated thread is created for the NanoMsg worker socket (REP) that serves the responses. You can experiment with creating multiple nanoMsg worker threads and stress testing it.

  1. #include "czmq.h"
  2. #include "nn.h"
  3. #include "reqrep.h"
  4.  
  5. #define WORKER_SOCKET_ADDRESS "inproc://test"
  6.  
  7. void* nano_worker(void* args)
  8. {
  9. int rc;
  10. int workerSock;
  11. char request[4096];
  12. char response[] = "HTTP / 1.0 200 OK\r\nContent - Type: text / plain\r\n\r\nHello World!!";
  13. int nResponseLen = strlen(response);
  14.  
  15. workerSock = nn_socket(AF_SP, NN_REP);
  16. assert(workerSock >= 0);
  17. nn_bind(workerSock, WORKER_SOCKET_ADDRESS);
  18. int i = 0;
  19. while (1)
  20. {
  21. rc = nn_recv(workerSock, request, sizeof (request), 0);
  22. assert(rc >= 0);
  23.  
  24. rc = nn_send(workerSock, response, nResponseLen+1, 0);
  25. assert(rc >= 0);
  26. }
  27. }
  28.  
  29. int main(void)
  30. {
  31. zctx_t *ctx = zctx_new();
  32. void *router = zsocket_new(ctx, ZMQ_ROUTER);
  33. zsocket_set_router_raw(router, 1);
  34. zsocket_set_sndhwm(router, 0);
  35. zsocket_set_rcvhwm(router, 0);
  36. int rc = zsocket_bind(router, "tcp://*:8080");
  37. assert(rc != -1);
  38.  
  39. zthread_new(nano_worker, NULL);
  40.  
  41. int sock = nn_socket(AF_SP, NN_REQ);
  42. assert(sock >= 0);
  43. assert(nn_connect(sock, WORKER_SOCKET_ADDRESS) >= 0);
  44.  
  45. while (true)
  46. {
  47. // Get HTTP request
  48. zframe_t *identity = zframe_recv(router);
  49. if (!identity) break; // Ctrl-C interrupt
  50. char *request = zstr_recv(router);
  51. {
  52. // forward the http-request to NanoMsg
  53. int bytes = nn_send(sock, request, strlen(request), 0);
  54. assert(bytes >= 0);
  55. }
  56. free(request); // free the memory
  57.  
  58. // read the response from NanoMsg worker
  59. char* response = NULL;
  60. int bytes = nn_recv(sock, &response, NN_MSG, 0);
  61. assert(bytes >= 0);
  62. {
  63. // Send response to client/browser
  64. zframe_send(&identity, router, ZFRAME_MORE + ZFRAME_REUSE);
  65. zstr_send(router, response);
  66.  
  67. // Close connection to browser
  68. zframe_send(&identity, router, ZFRAME_MORE);
  69. zmq_send(router, NULL, 0, 0);
  70. }
  71. nn_freemsg(response); // free the memory
  72. }
  73. zctx_destroy(&ctx);
  74. return 0;
  75. }

Report this snippet  

You need to login to post a comment.