1d4afb5ceSopenharmony_ci/* 2d4afb5ceSopenharmony_ci * lws-minimal-ws-client-ping 3d4afb5ceSopenharmony_ci * 4d4afb5ceSopenharmony_ci * Written in 2010-2020 by Andy Green <andy@warmcat.com> 5d4afb5ceSopenharmony_ci * 6d4afb5ceSopenharmony_ci * This file is made available under the Creative Commons CC0 1.0 7d4afb5ceSopenharmony_ci * Universal Public Domain Dedication. 8d4afb5ceSopenharmony_ci * 9d4afb5ceSopenharmony_ci * This demonstrates keeping a ws connection validated by the lws validity 10d4afb5ceSopenharmony_ci * timer stuff without having to do anything in the code. Use debug logging 11d4afb5ceSopenharmony_ci * -d1039 to see lws doing the pings / pongs in the background. 12d4afb5ceSopenharmony_ci */ 13d4afb5ceSopenharmony_ci 14d4afb5ceSopenharmony_ci#include <libwebsockets.h> 15d4afb5ceSopenharmony_ci#include <string.h> 16d4afb5ceSopenharmony_ci#include <signal.h> 17d4afb5ceSopenharmony_ci#if defined(WIN32) 18d4afb5ceSopenharmony_ci#define HAVE_STRUCT_TIMESPEC 19d4afb5ceSopenharmony_ci#if defined(pid_t) 20d4afb5ceSopenharmony_ci#undef pid_t 21d4afb5ceSopenharmony_ci#endif 22d4afb5ceSopenharmony_ci#endif 23d4afb5ceSopenharmony_ci#include <pthread.h> 24d4afb5ceSopenharmony_ci 25d4afb5ceSopenharmony_cistatic struct lws_context *context; 26d4afb5ceSopenharmony_cistatic struct lws *client_wsi; 27d4afb5ceSopenharmony_cistatic int interrupted, port = 443, ssl_connection = LCCSCF_USE_SSL; 28d4afb5ceSopenharmony_cistatic const char *server_address = "libwebsockets.org", *pro = "lws-mirror-protocol"; 29d4afb5ceSopenharmony_cistatic lws_sorted_usec_list_t sul; 30d4afb5ceSopenharmony_ci 31d4afb5ceSopenharmony_cistatic const lws_retry_bo_t retry = { 32d4afb5ceSopenharmony_ci .secs_since_valid_ping = 3, 33d4afb5ceSopenharmony_ci .secs_since_valid_hangup = 10, 34d4afb5ceSopenharmony_ci}; 35d4afb5ceSopenharmony_ci 36d4afb5ceSopenharmony_cistatic void 37d4afb5ceSopenharmony_ciconnect_cb(lws_sorted_usec_list_t *_sul) 38d4afb5ceSopenharmony_ci{ 39d4afb5ceSopenharmony_ci struct lws_client_connect_info i; 40d4afb5ceSopenharmony_ci 41d4afb5ceSopenharmony_ci lwsl_notice("%s: connecting\n", __func__); 42d4afb5ceSopenharmony_ci 43d4afb5ceSopenharmony_ci memset(&i, 0, sizeof(i)); 44d4afb5ceSopenharmony_ci 45d4afb5ceSopenharmony_ci i.context = context; 46d4afb5ceSopenharmony_ci i.port = port; 47d4afb5ceSopenharmony_ci i.address = server_address; 48d4afb5ceSopenharmony_ci i.path = "/"; 49d4afb5ceSopenharmony_ci i.host = i.address; 50d4afb5ceSopenharmony_ci i.origin = i.address; 51d4afb5ceSopenharmony_ci i.ssl_connection = ssl_connection; 52d4afb5ceSopenharmony_ci i.protocol = pro; 53d4afb5ceSopenharmony_ci i.alpn = "h2;http/1.1"; 54d4afb5ceSopenharmony_ci i.local_protocol_name = "lws-ping-test"; 55d4afb5ceSopenharmony_ci i.pwsi = &client_wsi; 56d4afb5ceSopenharmony_ci i.retry_and_idle_policy = &retry; 57d4afb5ceSopenharmony_ci 58d4afb5ceSopenharmony_ci if (!lws_client_connect_via_info(&i)) 59d4afb5ceSopenharmony_ci lws_sul_schedule(context, 0, _sul, connect_cb, 5 * LWS_USEC_PER_SEC); 60d4afb5ceSopenharmony_ci} 61d4afb5ceSopenharmony_ci 62d4afb5ceSopenharmony_cistatic int 63d4afb5ceSopenharmony_cicallback_minimal_pingtest(struct lws *wsi, enum lws_callback_reasons reason, 64d4afb5ceSopenharmony_ci void *user, void *in, size_t len) 65d4afb5ceSopenharmony_ci{ 66d4afb5ceSopenharmony_ci 67d4afb5ceSopenharmony_ci switch (reason) { 68d4afb5ceSopenharmony_ci 69d4afb5ceSopenharmony_ci case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: 70d4afb5ceSopenharmony_ci lwsl_err("CLIENT_CONNECTION_ERROR: %s\n", 71d4afb5ceSopenharmony_ci in ? (char *)in : "(null)"); 72d4afb5ceSopenharmony_ci lws_sul_schedule(context, 0, &sul, connect_cb, 5 * LWS_USEC_PER_SEC); 73d4afb5ceSopenharmony_ci break; 74d4afb5ceSopenharmony_ci 75d4afb5ceSopenharmony_ci case LWS_CALLBACK_CLIENT_ESTABLISHED: 76d4afb5ceSopenharmony_ci lwsl_user("%s: established\n", __func__); 77d4afb5ceSopenharmony_ci break; 78d4afb5ceSopenharmony_ci 79d4afb5ceSopenharmony_ci default: 80d4afb5ceSopenharmony_ci break; 81d4afb5ceSopenharmony_ci } 82d4afb5ceSopenharmony_ci 83d4afb5ceSopenharmony_ci return lws_callback_http_dummy(wsi, reason, user, in, len); 84d4afb5ceSopenharmony_ci} 85d4afb5ceSopenharmony_ci 86d4afb5ceSopenharmony_cistatic const struct lws_protocols protocols[] = { 87d4afb5ceSopenharmony_ci { 88d4afb5ceSopenharmony_ci "lws-ping-test", 89d4afb5ceSopenharmony_ci callback_minimal_pingtest, 90d4afb5ceSopenharmony_ci 0, 0, 0, NULL, 0 91d4afb5ceSopenharmony_ci }, 92d4afb5ceSopenharmony_ci LWS_PROTOCOL_LIST_TERM 93d4afb5ceSopenharmony_ci}; 94d4afb5ceSopenharmony_ci 95d4afb5ceSopenharmony_cistatic void 96d4afb5ceSopenharmony_cisigint_handler(int sig) 97d4afb5ceSopenharmony_ci{ 98d4afb5ceSopenharmony_ci interrupted = 1; 99d4afb5ceSopenharmony_ci} 100d4afb5ceSopenharmony_ci 101d4afb5ceSopenharmony_ciint main(int argc, const char **argv) 102d4afb5ceSopenharmony_ci{ 103d4afb5ceSopenharmony_ci struct lws_context_creation_info info; 104d4afb5ceSopenharmony_ci const char *p; 105d4afb5ceSopenharmony_ci int n = 0, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE 106d4afb5ceSopenharmony_ci /* for LLL_ verbosity above NOTICE to be built into lws, 107d4afb5ceSopenharmony_ci * lws must have been configured and built with 108d4afb5ceSopenharmony_ci * -DCMAKE_BUILD_TYPE=DEBUG instead of =RELEASE */ 109d4afb5ceSopenharmony_ci /* | LLL_INFO */ /* | LLL_PARSER */ /* | LLL_HEADER */ 110d4afb5ceSopenharmony_ci /* | LLL_EXT */ /* | LLL_CLIENT */ /* | LLL_LATENCY */ 111d4afb5ceSopenharmony_ci /* | LLL_DEBUG */; 112d4afb5ceSopenharmony_ci 113d4afb5ceSopenharmony_ci signal(SIGINT, sigint_handler); 114d4afb5ceSopenharmony_ci 115d4afb5ceSopenharmony_ci if ((p = lws_cmdline_option(argc, argv, "-d"))) 116d4afb5ceSopenharmony_ci logs = atoi(p); 117d4afb5ceSopenharmony_ci 118d4afb5ceSopenharmony_ci lws_set_log_level(logs, NULL); 119d4afb5ceSopenharmony_ci lwsl_user("LWS minimal ws client PING\n"); 120d4afb5ceSopenharmony_ci 121d4afb5ceSopenharmony_ci memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */ 122d4afb5ceSopenharmony_ci info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; 123d4afb5ceSopenharmony_ci info.port = CONTEXT_PORT_NO_LISTEN; /* we do not run any server */ 124d4afb5ceSopenharmony_ci info.protocols = protocols; 125d4afb5ceSopenharmony_ci#if defined(LWS_WITH_MBEDTLS) || defined(USE_WOLFSSL) 126d4afb5ceSopenharmony_ci /* 127d4afb5ceSopenharmony_ci * OpenSSL uses the system trust store. mbedTLS has to be told which 128d4afb5ceSopenharmony_ci * CA to trust explicitly. 129d4afb5ceSopenharmony_ci */ 130d4afb5ceSopenharmony_ci info.client_ssl_ca_filepath = "./libwebsockets.org.cer"; 131d4afb5ceSopenharmony_ci#endif 132d4afb5ceSopenharmony_ci 133d4afb5ceSopenharmony_ci if ((p = lws_cmdline_option(argc, argv, "--protocol"))) 134d4afb5ceSopenharmony_ci pro = p; 135d4afb5ceSopenharmony_ci 136d4afb5ceSopenharmony_ci if ((p = lws_cmdline_option(argc, argv, "--server"))) { 137d4afb5ceSopenharmony_ci server_address = p; 138d4afb5ceSopenharmony_ci pro = "lws-minimal"; 139d4afb5ceSopenharmony_ci ssl_connection |= LCCSCF_ALLOW_SELFSIGNED; 140d4afb5ceSopenharmony_ci } 141d4afb5ceSopenharmony_ci 142d4afb5ceSopenharmony_ci if ((p = lws_cmdline_option(argc, argv, "--port"))) 143d4afb5ceSopenharmony_ci port = atoi(p); 144d4afb5ceSopenharmony_ci 145d4afb5ceSopenharmony_ci info.fd_limit_per_thread = 1 + 1 + 1; 146d4afb5ceSopenharmony_ci 147d4afb5ceSopenharmony_ci context = lws_create_context(&info); 148d4afb5ceSopenharmony_ci if (!context) { 149d4afb5ceSopenharmony_ci lwsl_err("lws init failed\n"); 150d4afb5ceSopenharmony_ci return 1; 151d4afb5ceSopenharmony_ci } 152d4afb5ceSopenharmony_ci 153d4afb5ceSopenharmony_ci lws_sul_schedule(context, 0, &sul, connect_cb, 100); 154d4afb5ceSopenharmony_ci 155d4afb5ceSopenharmony_ci while (n >= 0 && !interrupted) 156d4afb5ceSopenharmony_ci n = lws_service(context, 0); 157d4afb5ceSopenharmony_ci 158d4afb5ceSopenharmony_ci lws_context_destroy(context); 159d4afb5ceSopenharmony_ci lwsl_user("Completed\n"); 160d4afb5ceSopenharmony_ci 161d4afb5ceSopenharmony_ci return 0; 162d4afb5ceSopenharmony_ci} 163