1/* 2 * lws-minimal-ws-client-pmd-bulk 3 * 4 * Written in 2010-2019 by Andy Green <andy@warmcat.com> 5 * 6 * This file is made available under the Creative Commons CC0 1.0 7 * Universal Public Domain Dedication. 8 * 9 * This demonstrates a ws client that sends bulk data in multiple 10 * ws fragments, in a way compatible with per-message deflate. 11 * 12 * It shows how to send huge messages without needing a lot of memory. 13 * 14 * Build and start the minimal-examples/ws-server/minmal-ws-server-pmd-bulk 15 * example first. Running this sends a large message to the server and 16 * exits. 17 * 18 * If you give both sides the -n commandline option, it disables permessage- 19 * deflate compression extension. 20 */ 21 22#include <libwebsockets.h> 23#include <string.h> 24#include <signal.h> 25 26#define LWS_PLUGIN_STATIC 27#include "protocol_lws_minimal_pmd_bulk.c" 28 29static struct lws_protocols protocols[] = { 30 { "http", lws_callback_http_dummy, 0, 0, 0, NULL, 0 }, 31 LWS_PLUGIN_PROTOCOL_MINIMAL_PMD_BULK, 32 LWS_PROTOCOL_LIST_TERM 33}; 34 35static int interrupted, options; 36 37/* pass pointers to shared vars to the protocol */ 38 39static const struct lws_protocol_vhost_options pvo_options = { 40 NULL, 41 NULL, 42 "options", /* pvo name */ 43 (void *)&options /* pvo value */ 44}; 45 46static const struct lws_protocol_vhost_options pvo_interrupted = { 47 &pvo_options, 48 NULL, 49 "interrupted", /* pvo name */ 50 (void *)&interrupted /* pvo value */ 51}; 52 53static const struct lws_protocol_vhost_options pvo = { 54 NULL, /* "next" pvo linked-list */ 55 &pvo_interrupted, /* "child" pvo linked-list */ 56 "lws-minimal-pmd-bulk", /* protocol name we belong to on this vhost */ 57 "" /* ignored */ 58}; 59static const struct lws_extension extensions[] = { 60 { 61 "permessage-deflate", 62 lws_extension_callback_pm_deflate, 63 "permessage-deflate" 64 "; client_no_context_takeover" 65 "; client_max_window_bits" 66 }, 67 { NULL, NULL, NULL /* terminator */ } 68}; 69 70void sigint_handler(int sig) 71{ 72 interrupted = 1; 73} 74 75int main(int argc, const char **argv) 76{ 77 struct lws_context_creation_info info; 78 struct lws_context *context; 79 const char *p; 80 int n = 0, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE 81 /* for LLL_ verbosity above NOTICE to be built into lws, 82 * lws must have been configured and built with 83 * -DCMAKE_BUILD_TYPE=DEBUG instead of =RELEASE */ 84 /* | LLL_INFO */ /* | LLL_PARSER */ /* | LLL_HEADER */ 85 /* | LLL_EXT */ /* | LLL_CLIENT */ /* | LLL_LATENCY */ 86 /* | LLL_DEBUG */; 87 88 signal(SIGINT, sigint_handler); 89 90 if ((p = lws_cmdline_option(argc, argv, "-d"))) 91 logs = atoi(p); 92 93 lws_set_log_level(logs, NULL); 94 lwsl_user("LWS minimal ws client + permessage-deflate + multifragment bulk message\n"); 95 lwsl_user(" needs minimal-ws-server-pmd-bulk running to communicate with\n"); 96 lwsl_user(" %s [-n (no exts)] [-c (compressible)]\n", argv[0]); 97 98 memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */ 99 info.port = CONTEXT_PORT_NO_LISTEN; 100 info.protocols = protocols; 101 info.pvo = &pvo; 102 if (!lws_cmdline_option(argc, argv, "-n")) 103 info.extensions = extensions; 104 info.pt_serv_buf_size = 32 * 1024; 105 106 if (lws_cmdline_option(argc, argv, "-c")) 107 options |= 1; 108 109 /* 110 * since we know this lws context is only ever going to be used with 111 * one client wsis / fds / sockets at a time, let lws know it doesn't 112 * have to use the default allocations for fd tables up to ulimit -n. 113 * It will just allocate for 1 internal and 1 (+ 1 http2 nwsi) that we 114 * will use. 115 */ 116 info.fd_limit_per_thread = 1 + 1 + 1; 117 118 context = lws_create_context(&info); 119 if (!context) { 120 lwsl_err("lws init failed\n"); 121 return 1; 122 } 123 124 while (n >= 0 && !interrupted) 125 n = lws_service(context, 0); 126 127 lws_context_destroy(context); 128 129 lwsl_user("Completed %s\n", interrupted == 2 ? "OK" : "failed"); 130 131 return interrupted != 2; 132} 133