Advertisement
Guest User

Websocket

a guest
Jun 6th, 2016
159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // libwebsocketsserver.cpp : Defines the entry point for the console application.
  2. //
  3.  
  4. #include "stdafx.h"
  5.  #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #ifdef _WIN32
  9. #include <io.h>
  10. #else
  11. #include <unistd.h>
  12. #endif
  13. #include <signal.h>
  14. #include <libwebsockets.h>
  15.  
  16. #define KGRN "\033[0;32;32m"
  17. #define KCYN "\033[0;36m"
  18. #define KRED "\033[0;32;31m"
  19. #define KYEL "\033[1;33m"
  20. #define KMAG "\033[0;35m"
  21. #define KBLU "\033[0;32;34m"
  22. #define KCYN_L "\033[1;36m"
  23. #define RESET "\033[0m"
  24.  
  25. static int destroy_flag = 0;
  26.  
  27. static void INT_HANDLER(int signo) {
  28.     destroy_flag = 1;
  29. }
  30.  
  31.  
  32. static int callback_http(
  33. struct lws *wsi,
  34. enum lws_callback_reasons reason, void *user,
  35.     void *in, size_t len)
  36. {
  37.  
  38.     switch (reason) {
  39.         // http://git.warmcat.com/cgi-bin/cgit/libwebsockets/tree/lib/libwebsockets.h#n260
  40.     case LWS_CALLBACK_CLIENT_WRITEABLE:
  41.         printf("connection established\n");
  42.  
  43.         // http://git.warmcat.com/cgi-bin/cgit/libwebsockets/tree/lib/libwebsockets.h#n281
  44.     case LWS_CALLBACK_HTTP: {
  45.         char *requested_uri = (char *)in;
  46.         printf("requested URI: %s\n", requested_uri);
  47.  
  48.         /*if (strcmp(requested_uri, "/") == 0) {
  49.             lws_return_http_status(wsi, 200, "Hello, World!\0");
  50.             // http://git.warmcat.com/cgi-bin/cgit/libwebsockets/tree/lib/libwebsockets.h#n597
  51.             //lws_write(wsi, universal_response,
  52.             //  strlen((const char*)universal_response), LWS_WRITE_HTTP);
  53.             lws_http_transaction_completed(wsi);
  54.             break;
  55.  
  56.         }
  57.         else {*/
  58.             if (strcmp(requested_uri, "index.html\0") != 0 && strcmp(requested_uri, "/\0") != 0) {
  59.                 printf("returning 404\n");
  60.                 lws_return_http_status(wsi, 404, "Only index.html is returned");
  61.                 lws_http_transaction_completed(wsi);
  62.                 break;
  63.             }
  64.  
  65.  
  66.             char *resource_path = "./index_cpp.html";
  67.                 printf("Returned resource path: %s\n", resource_path);
  68.                 char *mime = "text/html";
  69.                 // by default non existing resources return code 400
  70.                 // for more information how this function handles headers
  71.                 // see it's source code
  72.                 // http://git.warmcat.com/cgi-bin/cgit/libwebsockets/tree/lib/parsers.c#n1896
  73.                 lws_serve_http_file(wsi, resource_path, mime,"",0);
  74.         //}
  75.  
  76.         // close connection
  77.         lws_http_transaction_completed(wsi);
  78.         break;
  79.     }
  80.     //The following callbacks are ignored due to not being used
  81.     case LWS_CALLBACK_LOCK_POLL:
  82.         /*
  83.         * lock mutex to protect pollfd state
  84.         * called before any other POLL related callback
  85.         * if protecting wsi lifecycle change, len == 1
  86.         */
  87.         break;
  88.  
  89.     case LWS_CALLBACK_UNLOCK_POLL:
  90.         /*
  91.         * unlock mutex to protect pollfd state when
  92.         * called after any other POLL related callback
  93.         * if protecting wsi lifecycle change, len == 1
  94.         */
  95.         break;
  96.     case LWS_CALLBACK_GET_THREAD_ID:
  97.         break;
  98.     case LWS_CALLBACK_PROTOCOL_INIT:
  99.         break;
  100.     //If something unexpected pops up
  101.     default:
  102.         printf("unhandled callback %d\n ", reason);
  103.         break;
  104.     }
  105.  
  106.    
  107.  
  108.     return 0;
  109. }
  110.  
  111.  
  112. char *randstring(int length) {
  113.     static int mySeed = 25011984;
  114.     char *string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,.-#'?!";
  115.     size_t stringLen = strlen(string);
  116.     char *randomString = NULL;
  117.  
  118.     srand((unsigned int)time(NULL) * length + ++mySeed);
  119.  
  120.     if (length < 1) {
  121.         length = 1;
  122.     }
  123.  
  124.     randomString = (char *)malloc(sizeof(char) * (length + 1));
  125.  
  126.     if (randomString) {
  127.         short key = 0;
  128.  
  129.         for (int n = 0; n < length; n++) {
  130.             key = rand() % stringLen;
  131.             randomString[n] = string[key];
  132.         }
  133.  
  134.         randomString[length] = '\0';
  135.  
  136.         return randomString;
  137.     }
  138.     else {
  139.         printf("No memory");
  140.         exit(1);
  141.     }
  142. }
  143.  
  144. const int replySize = 30000;
  145.  
  146. char *reply_string = randstring(replySize);
  147.  
  148.  
  149.  
  150. /* *
  151. * websocket_write_back: write the string data to the destination wsi.
  152. */
  153. int websocket_write_back(struct lws *wsi_in, char *str, int str_size_in)
  154. {
  155.     //if (str == NULL || wsi_in == NULL)
  156.     //  return -1;
  157.  
  158.     int n;
  159.     int len;
  160.     unsigned char *out = NULL;
  161.  
  162.     char *write_what = reply_string;
  163.  
  164.     //if (str_size_in < 1)
  165.         len = strlen(write_what);
  166.     //else
  167.         //len = str_size_in;
  168.  
  169.     out = (unsigned char *)malloc(sizeof(char)*(LWS_SEND_BUFFER_PRE_PADDING + len + LWS_SEND_BUFFER_POST_PADDING));
  170.     //* setup the buffer*/
  171.     memcpy(out + LWS_SEND_BUFFER_PRE_PADDING, write_what, len);
  172.     //* write out*/
  173.     n = lws_write(wsi_in, out + LWS_SEND_BUFFER_PRE_PADDING, len, LWS_WRITE_TEXT);
  174.  
  175.     //printf(KBLU"[websocket_write_back] %s\n"RESET, write_what);
  176.     //* free the buffer*/
  177.     free(out);
  178.  
  179.     return n;
  180. }
  181.  
  182. static int ws_service_callback(
  183.     struct lws *wsi,
  184.     enum lws_callback_reasons reason,
  185.     void *user,
  186.     void *in, size_t len)
  187. {
  188.  
  189.     printf("Got a ws request %d\n", reason);
  190.  
  191.     switch (reason) {
  192.  
  193.     case LWS_CALLBACK_ESTABLISHED:
  194.         printf(KYEL"[Main Service] Connection established\n"RESET);
  195.         break;
  196.  
  197.         //* If receive a data from client*/
  198.     case LWS_CALLBACK_RECEIVE:
  199.         printf(KCYN_L"[Main Service] Server recvived:\n"RESET/*, (char *)in*/);
  200.  
  201.         //* echo back to client*/
  202.         websocket_write_back(wsi, (char *)in, -1);
  203.  
  204.         break;
  205.     case LWS_CALLBACK_CLOSED:
  206.         printf(KYEL"[Main Service] Client close.\n"RESET);
  207.         break;
  208.  
  209.     default:
  210.         break;
  211.     }
  212.  
  213.     return 0;
  214. }
  215.  
  216. struct per_session_data {
  217.     int fd;
  218. };
  219.  
  220. bool got_sighup = false;
  221. bool got_sigint = false;
  222.  
  223. void handle_signal(int signal) {
  224.     switch (signal) {
  225. #ifdef _WIN32
  226.     case SIGTERM:
  227.     case SIGABRT:
  228.     case SIGBREAK:
  229. #else
  230.     case SIGHUP:
  231. #endif
  232.         got_sighup = true;
  233.         break;
  234.     case SIGINT:
  235.         got_sigint = true;
  236.         break;
  237.     }
  238. }
  239. #ifdef _WIN32
  240.  
  241. void usleep(__int64 usec)
  242. {
  243.     HANDLE timer;
  244.     LARGE_INTEGER ft;
  245.  
  246.     ft.QuadPart = -(10 * usec); // Convert to 100 nanosecond interval, negative value indicates relative time
  247.  
  248.     timer = CreateWaitableTimer(NULL, TRUE, NULL);
  249.     SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0);
  250.     WaitForSingleObject(timer, INFINITE);
  251.     CloseHandle(timer);
  252. }
  253. #endif
  254.  
  255. struct per_session_data__http {
  256.     lws_filefd_type fd;
  257.     char post_string[256];
  258. #ifdef LWS_WITH_CGI
  259.     struct lws_cgi_args args;
  260. #endif
  261. #if defined(LWS_WITH_CGI) || !defined(LWS_NO_CLIENT)
  262.     int reason_bf;
  263. #endif
  264.     unsigned int client_finished : 1;
  265. };
  266.  
  267.  
  268. static struct lws_protocols protocols[] = {
  269.     /* first protocol must always be HTTP handler */
  270.  
  271.     {
  272.         "http-only",        /* name */
  273.         callback_http,      /* callback */
  274.         sizeof(struct per_session_data__http)/* per_session_data_size */
  275.         0,          /* max frame size / rx buffer */
  276.     },
  277.     {
  278.         "tspp",
  279.         ws_service_callback,
  280.         sizeof(struct per_session_data),
  281.         0, /* rx buf size must be >= permessage-deflate rx size */
  282.     },
  283.     { NULL, NULL, 0, 0 } /* terminator */
  284. };
  285.  
  286.  
  287. int _tmain(int argc, _TCHAR* argv[])
  288. {
  289.     // server url will usd port 5000
  290.     int port = 5000;
  291.     const char *interface = NULL;
  292.     struct lws_context_creation_info info;
  293.     struct lws_context *context;
  294.     // Not using ssl
  295.     const char *cert_path = NULL;
  296.     const char *key_path = NULL;
  297.     // no special options
  298.     int opts = 0;
  299.  
  300. #ifdef _WIN32
  301.     signal(SIGINT, handle_signal);
  302.     signal(SIGTERM, handle_signal);
  303.     signal(SIGABRT, handle_signal);
  304. #else
  305.  
  306.     //* register the signal SIGINT handler */
  307.     struct sigaction  act;
  308.     act.sa_handler = INT_HANDLER;
  309.     act.sa_flags = 0;
  310.     sigemptyset(&act.sa_mask);
  311.     sigaction(SIGINT, &act, 0);
  312. #endif
  313.  
  314.     //* setup websocket protocol */
  315.  
  316.     //* setup websocket context info*/
  317.     memset(&info, 0, sizeof info);
  318.     info.port = port;
  319.     info.iface = interface;
  320.     info.protocols = protocols;
  321.  
  322.     info.extensions = lws_get_internal_extensions();
  323.     info.ssl_cert_filepath = cert_path;
  324.     info.ssl_private_key_filepath = key_path;
  325.     info.gid = -1;
  326.     info.uid = -1;
  327.     info.options = opts;
  328.  
  329.     //* create libwebsocket context. */
  330.     context = lws_create_context(&info);
  331.     if (context == NULL) {
  332.         printf(KRED"[Main] Websocket context create error.\n"RESET);
  333.         return -1;
  334.     }
  335.  
  336.     printf(KGRN"[Main] Websocket context create success.\n"RESET);
  337.  
  338.     //* websocket service */
  339.     while (!destroy_flag) {
  340.         lws_service(context, 0);
  341.     }
  342.     usleep(10);
  343.     lws_context_destroy(context);
  344.  
  345.     return 0;
  346.     return 0;
  347. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement