Guest User

libwebsockets example

a guest
Nov 17th, 2019
361
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.21 KB | None | 0 0
  1.  
  2. #include <libwebsockets.h>
  3. #include <string.h>
  4. #include <signal.h>
  5. #include <iostream>
  6. using namespace std;
  7.  
  8. #define LWS_PLUGIN_STATIC
  9. #include "protocol_lws_minimal.c"
  10.  
  11. static struct lws_protocols protocols[] = {
  12.         { "http", lws_callback_http_dummy, 0, 0 },
  13.         LWS_PLUGIN_PROTOCOL_MINIMAL,
  14.         { NULL, NULL, 0, 0 } /* terminator */
  15. };
  16.  
  17. static int interrupted;
  18.  
  19. static const struct lws_http_mount mount = {
  20.         /* .mount_next */               NULL,           /* linked-list "next" */
  21.         /* .mountpoint */               "/",            /* mountpoint URL */
  22.         /* .origin */                   "./mount-origin",  /* serve from dir */
  23.         /* .def */                      "index.html",   /* default filename */
  24.         /* .protocol */                 NULL,
  25.         /* .cgienv */                   NULL,
  26.         /* .extra_mimetypes */          NULL,
  27.         /* .interpret */                NULL,
  28.         /* .cgi_timeout */              0,
  29.         /* .cache_max_age */            0,
  30.         /* .auth_mask */                0,
  31.         /* .cache_reusable */           0,
  32.         /* .cache_revalidate */         0,
  33.         /* .cache_intermediaries */     0,
  34.         /* .origin_protocol */          LWSMPRO_FILE,   /* files in a dir */
  35.         /* .mountpoint_len */           1,              /* char count */
  36.         /* .basic_auth_login_file */    NULL,
  37. };
  38.  
  39. void sigint_handler(int sig)
  40. {
  41.         interrupted = 1;
  42. }
  43. int main(int argc, const char **argv)
  44. {
  45.         struct lws_context_creation_info info;
  46.         struct lws_context *context;
  47.         const char *p;
  48.         int n = 0, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE
  49.                         /* for LLL_ verbosity above NOTICE to be built into lws,
  50.                          * lws must have been configured and built with
  51.                          * -DCMAKE_BUILD_TYPE=DEBUG instead of =RELEASE */
  52.                         /* | LLL_INFO */ /* | LLL_PARSER */ /* | LLL_HEADER */
  53.                         /* | LLL_EXT */ /* | LLL_CLIENT */ /* | LLL_LATENCY */
  54.                         /* | LLL_DEBUG */;
  55.  
  56.         cout << "start!\n";
  57.         signal(SIGINT, sigint_handler);
  58.  
  59.         if ((p = lws_cmdline_option(argc, argv, "-d")))
  60.                 logs = atoi(p);
  61.  
  62.         lws_set_log_level(logs, NULL);
  63.         lwsl_user("LWS minimal ws server | visit http://localhost:7681 (-s = use TLS / https)\n");
  64.  
  65.         memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */
  66.         info.port = 7681;
  67.         info.mounts = &mount;
  68.         info.protocols = protocols;
  69.         info.vhost_name = "localhost";
  70.         info.ws_ping_pong_interval = 10;
  71.         info.options =
  72.                 LWS_SERVER_OPTION_HTTP_HEADERS_SECURITY_BEST_PRACTICES_ENFORCE;
  73.  
  74.         if (lws_cmdline_option(argc, argv, "-s")) {
  75.                 lwsl_user("Server using TLS\n");
  76.                 info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
  77.                 info.ssl_cert_filepath = "localhost-100y.cert";
  78.                 info.ssl_private_key_filepath = "localhost-100y.key";
  79.         }
  80.  
  81.         if (lws_cmdline_option(argc, argv, "-h"))
  82.                 info.options |= LWS_SERVER_OPTION_VHOST_UPG_STRICT_HOST_CHECK;
  83.  
  84.         context = lws_create_context(&info);
  85.         if (!context) {
  86.                 lwsl_err("lws init failed\n");
  87.                 return 1;
  88.         }
  89.  
  90.         while (n >= 0 && !interrupted)
  91.                 n = lws_service(context, 1000);
  92.  
  93.         lws_context_destroy(context);
  94.  
  95.         return 0;
  96. }
  97.  
  98.  
  99.  
  100.  
  101.  
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112.  
  113.  
  114.  
  115.  
  116. /*
  117.  * ws protocol handler plugin for "lws-minimal"
  118.  *
  119.  * Written in 2010-2019 by Andy Green <[email protected]>
  120.  *
  121.  * This file is made available under the Creative Commons CC0 1.0
  122.  * Universal Public Domain Dedication.
  123.  *
  124.  * This version holds a single message at a time, which may be lost if a new
  125.  * message comes.  See the minimal-ws-server-ring sample for the same thing
  126.  * but using an lws_ring ringbuffer to hold up to 8 messages at a time.
  127.  */
  128.  
  129. #if !defined(LWS_PLUGIN_STATIC)
  130. #define LWS_DLL
  131. #define LWS_INTERNAL
  132. #include <libwebsockets.h>
  133. #endif
  134.  
  135. #include <string.h>
  136.  
  137. /* one of these created for each message */
  138.  
  139. struct msg
  140. {
  141.     void *payload; /* is malloc'd */
  142.     size_t len;
  143. };
  144.  
  145. /* one of these is created for each client connecting to us */
  146.  
  147. struct per_session_data__minimal
  148. {
  149.     struct per_session_data__minimal *pss_list;
  150.     struct lws *wsi;
  151.     int last; /* the last message number we sent */
  152. };
  153.  
  154. /* one of these is created for each vhost our protocol is used with */
  155.  
  156. struct per_vhost_data__minimal
  157. {
  158.     struct lws_context *context;
  159.     struct lws_vhost *vhost;
  160.     const struct lws_protocols *protocol;
  161.  
  162.     struct per_session_data__minimal *pss_list; /* linked-list of live pss*/
  163.  
  164.     struct msg amsg; /* the one pending message... */
  165.     int current;     /* the current message number we are caching */
  166. };
  167.  
  168. /* destroys the message when everyone has had a copy of it */
  169.  
  170. static void
  171. __minimal_destroy_message(void *_msg)
  172. {
  173.     struct msg *msg = _msg;
  174.  
  175.     free(msg->payload);
  176.     msg->payload = NULL;
  177.     msg->len = 0;
  178. }
  179.  
  180. static int
  181. callback_minimal(struct lws *wsi, enum lws_callback_reasons reason,
  182.                  void *user, void *in, size_t len)
  183. {
  184.     struct per_session_data__minimal *pss =
  185.         (struct per_session_data__minimal *)user;
  186.     struct per_vhost_data__minimal *vhd =
  187.         (struct per_vhost_data__minimal *)
  188.             lws_protocol_vh_priv_get(lws_get_vhost(wsi),
  189.                                      lws_get_protocol(wsi));
  190.  
  191.     string *cordovaMessage;
  192.     char *cordovaTemp = new char[len + 1]; //do konwersji void * > string *
  193.  
  194.     int m;
  195.     cerr << "CALLBACK:" << reason << " \n";
  196.     switch (reason)
  197.     {
  198.     case LWS_CALLBACK_PROTOCOL_INIT:
  199.         vhd = lws_protocol_vh_priv_zalloc(lws_get_vhost(wsi),
  200.                                           lws_get_protocol(wsi),
  201.                                           sizeof(struct per_vhost_data__minimal));
  202.         vhd->context = lws_get_context(wsi);
  203.         vhd->protocol = lws_get_protocol(wsi);
  204.         vhd->vhost = lws_get_vhost(wsi);
  205.         cerr << "----INIT\n";
  206.         break;
  207.  
  208.     case LWS_CALLBACK_ESTABLISHED:
  209.         /* add ourselves to the list of live pss held in the vhd */
  210.         lws_ll_fwd_insert(pss, pss_list, vhd->pss_list);
  211.         pss->wsi = wsi;
  212.         pss->last = vhd->current;
  213.         cerr << "----ESTABLISHED\n";
  214.         break;
  215.  
  216.     case LWS_CALLBACK_CLOSED:
  217.         /* remove our closing pss from the list of live pss */
  218.         lws_ll_fwd_remove(struct per_session_data__minimal, pss_list,
  219.                           pss, vhd->pss_list);
  220.         cerr << "----CLOSED\n";
  221.         break;
  222.  
  223.     case LWS_CALLBACK_SERVER_WRITEABLE:
  224.         if (!vhd->amsg.payload)
  225.             break;
  226.  
  227.         if (pss->last == vhd->current)
  228.             break;
  229.  
  230.         /* notice we allowed for LWS_PRE in the payload already */
  231.         m = lws_write(wsi, ((unsigned char *)vhd->amsg.payload) + LWS_PRE, vhd->amsg.len, LWS_WRITE_TEXT);
  232.         if (m < (int)vhd->amsg.len)
  233.         {
  234.             lwsl_err("ERROR %d writing to ws\n", m);
  235.             return -1;
  236.         }
  237.  
  238.         pss->last = vhd->current;
  239.         cerr << "----WRITABLE\n";
  240.  
  241.         break;
  242.  
  243.     case LWS_CALLBACK_RECEIVE:
  244.         if (vhd->amsg.payload)
  245.             __minimal_destroy_message(&vhd->amsg);
  246.  
  247.         vhd->amsg.len = len;
  248.         /* notice we over-allocate by LWS_PRE */
  249.         vhd->amsg.payload = malloc(LWS_PRE + len);
  250.         if (!vhd->amsg.payload)
  251.         {
  252.             lwsl_user("OOM: dropping\n");
  253.             break;
  254.         }
  255.  
  256.         memcpy((char *)vhd->amsg.payload + LWS_PRE, in, len);
  257.         //TU MOŻNA ODCZYTAĆ TRANSMISJĘ PRZYCHODZĄCĄ np. do zmiennej typu std::string *
  258.         memcpy(cordovaTemp, in, len); //kopiowanie z void * do char *
  259.         cordovaTemp[len] = '\0';      //dodanie znaku konca stringu (brakowalo)
  260.  
  261.         cordovaMessage = new string(cordovaTemp);
  262.         cerr << "Got cordova message: " << *cordovaMessage << "\n";
  263.         delete cordovaMessage; //jak niepotrzebne - usuwamy
  264.                                //^ /////////////////////////////////////////////////////////////////////
  265.  
  266.         vhd->current++;
  267.  
  268.         /*
  269.                  * let everybody know we want to write something on them
  270.                  * as soon as they are ready
  271.                  */
  272.         lws_start_foreach_llp(struct per_session_data__minimal **,
  273.                               ppss, vhd->pss_list)
  274.         {
  275.             lws_callback_on_writable((*ppss)->wsi);
  276.         }
  277.         lws_end_foreach_llp(ppss, pss_list);
  278.         cerr << "----RECEIVE\n";
  279.  
  280.         break;
  281.     case LWS_CALLBACK_ADD_HEADERS:
  282.         cerr << "---HEADERS\n";
  283.  
  284.         break;
  285.     default:
  286.         break;
  287.     }
  288.  
  289.     delete[] cordovaTemp;
  290.     return 0;
  291. }
  292.  
  293. #define LWS_PLUGIN_PROTOCOL_MINIMAL                   \
  294.     {                                                 \
  295.         "lws-minimal",                                \
  296.             callback_minimal,                         \
  297.             sizeof(struct per_session_data__minimal), \
  298.             128,                                      \
  299.             0, NULL, 0                                \
  300.     }
  301.  
  302. #if !defined(LWS_PLUGIN_STATIC)
  303.  
  304. /* boilerplate needed if we are built as a dynamic plugin */
  305.  
  306. static const struct lws_protocols protocols[] = {
  307.     LWS_PLUGIN_PROTOCOL_MINIMAL};
  308.  
  309. LWS_EXTERN LWS_VISIBLE int
  310. init_protocol_minimal(struct lws_context *context,
  311.                       struct lws_plugin_capability *c)
  312. {
  313.     if (c->api_magic != LWS_PLUGIN_API_MAGIC)
  314.     {
  315.         lwsl_err("Plugin API %d, library API %d", LWS_PLUGIN_API_MAGIC,
  316.                  c->api_magic);
  317.         return 1;
  318.     }
  319.  
  320.     c->protocols = protocols;
  321.     c->count_protocols = LWS_ARRAY_SIZE(protocols);
  322.     c->extensions = NULL;
  323.     c->count_extensions = 0;
  324.  
  325.     return 0;
  326. }
  327.  
  328. LWS_EXTERN LWS_VISIBLE int
  329. destroy_protocol_minimal(struct lws_context *context)
  330. {
  331.     return 0;
  332. }
  333. #endif
Advertisement
Add Comment
Please, Sign In to add comment