diff --git a/minimal-examples/minimal-http-client/minimal-http-client.c b/minimal-examples/minimal-http-client/minimal-http-client.c index 45348c1d..8e9ba0a4 100644 --- a/minimal-examples/minimal-http-client/minimal-http-client.c +++ b/minimal-examples/minimal-http-client/minimal-http-client.c @@ -14,7 +14,9 @@ #include #include +#include +static int interrupted; static struct lws *client_wsi; static int @@ -79,6 +81,12 @@ static const struct lws_protocols protocols[] = { { NULL, NULL, 0, 0 } }; +static void +sigint_handler(int sig) +{ + interrupted = 1; +} + int main(int argc, char **argv) { struct lws_context_creation_info info; @@ -86,6 +94,7 @@ int main(int argc, char **argv) struct lws_context *context; int n = 0; + signal(SIGINT, sigint_handler); lws_set_log_level(LLL_ERR | LLL_WARN | LLL_NOTICE | LLL_USER /* | LLL_INFO */ /* | LLL_DEBUG */, NULL); lwsl_user("LWS minimal http client\n"); @@ -116,7 +125,7 @@ int main(int argc, char **argv) i.pwsi = &client_wsi; lws_client_connect_via_info(&i); - while (n >= 0 && client_wsi) + while (n >= 0 && client_wsi && !interrupted) n = lws_service(context, 1000); lws_context_destroy(context); diff --git a/minimal-examples/minimal-ws-client/CMakeLists.txt b/minimal-examples/minimal-ws-client/CMakeLists.txt new file mode 100644 index 00000000..2c8ff3de --- /dev/null +++ b/minimal-examples/minimal-ws-client/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 2.8) + +set(SAMP lws-minimal-ws-client) +set(SRCS minimal-ws-client.c) + +if (UNIX) + set(CMAKE_C_FLAGS "-Wall -Wsign-compare -Wignored-qualifiers -Wtype-limits -Wuninitialized -Werror -Wundef ${CMAKE_C_FLAGS}" ) +endif() + +add_executable(${SAMP} ${SRCS}) +target_link_libraries(${SAMP} -lwebsockets) + diff --git a/minimal-examples/minimal-ws-client/README.md b/minimal-examples/minimal-ws-client/README.md new file mode 100644 index 00000000..f3a0b822 --- /dev/null +++ b/minimal-examples/minimal-ws-client/README.md @@ -0,0 +1,35 @@ +# lws minimal ws client + +## build + +``` + $ cmake . && make +``` + +## usage + +The application goes to https://libwebsockets.org and makes a wss connection +using the dumb-increment-protocol. It shows the incrementing number it is +being sent over ws as it arrives. + +``` +./lws-minimal-ws-client +[2018/03/14 11:57:24:0689] USER: LWS minimal ws client +[2018/03/14 11:57:24:0705] NOTICE: Creating Vhost 'default' port -1, 1 protocols, IPv6 off +[2018/03/14 11:57:24:0710] NOTICE: created client ssl context for default +[2018/03/14 11:57:24:0788] NOTICE: lws_client_connect_2: 0x15b8310: address libwebsockets.org +[2018/03/14 11:57:24:7643] NOTICE: lws_client_connect_2: 0x15b8310: address libwebsockets.org +[2018/03/14 11:57:26:9191] USER: RX: 0 +[2018/03/14 11:57:26:9318] USER: RX: 1 +[2018/03/14 11:57:27:2182] USER: RX: 2 +[2018/03/14 11:57:27:2336] USER: RX: 3 +[2018/03/14 11:57:27:2838] USER: RX: 4 +[2018/03/14 11:57:27:5173] USER: RX: 5 +[2018/03/14 11:57:27:5352] USER: RX: 6 +[2018/03/14 11:57:27:5854] USER: RX: 7 +[2018/03/14 11:57:27:8156] USER: RX: 8 +[2018/03/14 11:57:27:8359] USER: RX: 9 +^C[2018/03/14 11:57:27:9884] USER: Completed +``` + + diff --git a/minimal-examples/minimal-ws-client/minimal-ws-client.c b/minimal-examples/minimal-ws-client/minimal-ws-client.c new file mode 100644 index 00000000..c040dcba --- /dev/null +++ b/minimal-examples/minimal-ws-client/minimal-ws-client.c @@ -0,0 +1,117 @@ +/* + * lws-minimal-ws-client + * + * Copyright (C) 2018 Andy Green + * + * This file is made available under the Creative Commons CC0 1.0 + * Universal Public Domain Dedication. + * + * This demonstrates the a minimal http client using lws. + * + * It connects to https://libwebsockets.org/ and makes a + * wss connection to the dumb-increment protocol there. While + * connected, it prints the numbers it is being sent by + * dumb-increment protocol. + */ + +#include +#include +#include + +static int interrupted; +static struct lws *client_wsi; + +static int +callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason, + void *user, void *in, size_t len) +{ + switch (reason) { + + /* because we are protocols[0] ... */ + case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: + lwsl_err("CLIENT_CONNECTION_ERROR: %s\n", + in ? (char *)in : "(null)"); + client_wsi = NULL; + break; + + case LWS_CALLBACK_CLIENT_ESTABLISHED: + lwsl_user("%s: established\n", __func__); + break; + + case LWS_CALLBACK_CLIENT_RECEIVE: + lwsl_user("RX: %s\n", (const char *)in); + break; + + case LWS_CALLBACK_CLOSED: + client_wsi = NULL; + break; + + default: + break; + } + + return lws_callback_http_dummy(wsi, reason, user, in, len); +} + +static const struct lws_protocols protocols[] = { + { + "dumb-increment-protocol", + callback_dumb_increment, + 0, + 0, + }, + { NULL, NULL, 0, 0 } +}; + +static void +sigint_handler(int sig) +{ + interrupted = 1; +} + +int main(int argc, char **argv) +{ + struct lws_context_creation_info info; + struct lws_client_connect_info i; + struct lws_context *context; + int n = 0; + + signal(SIGINT, sigint_handler); + + lws_set_log_level(LLL_ERR | LLL_WARN | LLL_NOTICE | LLL_USER + /* | LLL_INFO */ /* | LLL_DEBUG */, NULL); + lwsl_user("LWS minimal ws client\n"); + + memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */ + info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; + info.port = CONTEXT_PORT_NO_LISTEN; /* we do not run any server */ + info.protocols = protocols; + + context = lws_create_context(&info); + if (!context) { + lwsl_err("lws init failed\n"); + return 1; + } + + memset(&i, 0, sizeof i); /* otherwise uninitialized garbage */ + i.context = context; + + i.port = 443; + i.address = "libwebsockets.org"; + i.path = "/"; + i.host = i.address; + i.origin = i.address; + i.ssl_connection = 1; + + i.protocol = protocols[0].name; /* "dumb-increment-protocol" */ + i.pwsi = &client_wsi; + lws_client_connect_via_info(&i); + + while (n >= 0 && client_wsi && !interrupted) + n = lws_service(context, 1000); + + lws_context_destroy(context); + lwsl_user("Completed\n"); + + return 0; +}