mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
minimal: add Wall and cleanups
This commit is contained in:
parent
388c0677ee
commit
b49630e515
19 changed files with 203 additions and 82 deletions
|
@ -1,10 +1,12 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(lws-minimal-http-client C)
|
||||
|
||||
set(SAMP lws-minimal-http-client)
|
||||
set(SRCS minimal-http-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)
|
||||
|
||||
|
|
|
@ -21,8 +21,6 @@ static int
|
|||
callback_http(struct lws *wsi, enum lws_callback_reasons reason,
|
||||
void *user, void *in, size_t len)
|
||||
{
|
||||
const char *p = in;
|
||||
|
||||
switch (reason) {
|
||||
|
||||
/* because we are protocols[0] ... */
|
||||
|
@ -36,11 +34,15 @@ callback_http(struct lws *wsi, enum lws_callback_reasons reason,
|
|||
case LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ:
|
||||
lwsl_user("RECEIVE_CLIENT_HTTP_READ: read %d\n", (int)len);
|
||||
#if 0 /* enable to dump the html */
|
||||
while (len--)
|
||||
if (*p < 0x7f)
|
||||
putchar(*p++);
|
||||
else
|
||||
putchar('.');
|
||||
{
|
||||
const char *p = in;
|
||||
|
||||
while (len--)
|
||||
if (*p < 0x7f)
|
||||
putchar(*p++);
|
||||
else
|
||||
putchar('.');
|
||||
}
|
||||
#endif
|
||||
return 0; /* don't passthru */
|
||||
|
||||
|
|
18
minimal-examples/minimal-http-server-smp/CMakeLists.txt
Normal file
18
minimal-examples/minimal-http-server-smp/CMakeLists.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
include(CheckIncludeFile)
|
||||
|
||||
set(SAMP lws-minimal-http-server-smp)
|
||||
set(SRCS minimal-http-server-smp.c)
|
||||
|
||||
if (UNIX)
|
||||
set(CMAKE_C_FLAGS "-Wall -Wsign-compare -Wignored-qualifiers -Wtype-limits -Wuninitialized -Werror -Wundef ${CMAKE_C_FLAGS}" )
|
||||
endif()
|
||||
|
||||
CHECK_INCLUDE_FILE(pthread.h LWS_HAVE_PTHREAD_H)
|
||||
if (NOT LWS_HAVE_PTHREAD_H)
|
||||
message(FATAL_ERROR "smp support requires pthreads")
|
||||
endif()
|
||||
|
||||
add_executable(${SAMP} ${SRCS})
|
||||
target_link_libraries(${SAMP} -lwebsockets -lpthread)
|
||||
|
19
minimal-examples/minimal-http-server-smp/README.md
Normal file
19
minimal-examples/minimal-http-server-smp/README.md
Normal file
|
@ -0,0 +1,19 @@
|
|||
# lws minimal http server with multithreaded service
|
||||
|
||||
## build
|
||||
|
||||
```
|
||||
$ cmake . && make
|
||||
```
|
||||
|
||||
## usage
|
||||
|
||||
```
|
||||
$ ./lws-minimal-http-server-smp
|
||||
[2018/03/07 17:44:20:2409] USER: LWS minimal http server SMP | visit http://localhost:7681
|
||||
[2018/03/07 17:44:20:2410] NOTICE: Creating Vhost 'default' port 7681, 1 protocols, IPv6 on
|
||||
[2018/03/07 17:44:20:2411] NOTICE: Service threads: 10
|
||||
```
|
||||
|
||||
Visit http://localhost:7681 and use ab or other testing tools
|
||||
|
BIN
minimal-examples/minimal-http-server-smp/favicon.ico
Normal file
BIN
minimal-examples/minimal-http-server-smp/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
9
minimal-examples/minimal-http-server-smp/index.html
Normal file
9
minimal-examples/minimal-http-server-smp/index.html
Normal file
|
@ -0,0 +1,9 @@
|
|||
<meta charset="UTF-8">
|
||||
<html>
|
||||
<body>
|
||||
<img src="libwebsockets.org-logo.png"><br>
|
||||
|
||||
Hello from the <b>minimal http server SMP example</b>.
|
||||
</body>
|
||||
</html>
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 6.9 KiB |
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* lws-minimal-http-server-smp
|
||||
*
|
||||
* Copyright (C) 2018 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* This file is made available under the Creative Commons CC0 1.0
|
||||
* Universal Public Domain Dedication.
|
||||
*
|
||||
* This demonstrates a minimal multithreaded http server you can make with lws.
|
||||
*
|
||||
* To keep it simple, it serves stuff in the directory it was started in.
|
||||
* You can change that by changing mount.origin.
|
||||
*
|
||||
* Also for simplicity the number of threads is set in the code... note that
|
||||
* the real number of threads possible is decided by the LWS_MAX_SMP that lws
|
||||
* was configured with, by default that is 1. Lws will limit the number of
|
||||
* requested threads to the number possible.
|
||||
*/
|
||||
|
||||
#include <libwebsockets.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#define COUNT_THREADS 10
|
||||
|
||||
static struct lws_context *context;
|
||||
static int interrupted;
|
||||
|
||||
static const struct lws_http_mount mount = {
|
||||
/* .mount_next */ NULL, /* linked-list "next" */
|
||||
/* .mountpoint */ "/", /* mountpoint URL */
|
||||
/* .origin */ ".", /* serve from dir */
|
||||
/* .def */ "index.html", /* default filename */
|
||||
/* .protocol */ NULL,
|
||||
/* .cgienv */ NULL,
|
||||
/* .extra_mimetypes */ NULL,
|
||||
/* .interpret */ NULL,
|
||||
/* .cgi_timeout */ 0,
|
||||
/* .cache_max_age */ 0,
|
||||
/* .auth_mask */ 0,
|
||||
/* .cache_reusable */ 0,
|
||||
/* .cache_revalidate */ 0,
|
||||
/* .cache_intermediaries */ 0,
|
||||
/* .origin_protocol */ LWSMPRO_FILE, /* files in a dir */
|
||||
/* .mountpoint_len */ 1, /* char count */
|
||||
/* .basic_auth_login_file */ NULL,
|
||||
};
|
||||
|
||||
void *thread_service(void *threadid)
|
||||
{
|
||||
while (lws_service_tsi(context, 50, (int)(lws_intptr_t)threadid) >= 0 &&
|
||||
!interrupted)
|
||||
;
|
||||
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
void sigint_handler(int sig)
|
||||
{
|
||||
interrupted = 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
pthread_t pthread_service[COUNT_THREADS];
|
||||
struct lws_context_creation_info info;
|
||||
void *retval;
|
||||
int n = 0;
|
||||
|
||||
signal(SIGINT, sigint_handler);
|
||||
|
||||
memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */
|
||||
info.port = 7681;
|
||||
info.mounts = &mount;
|
||||
info.count_threads = COUNT_THREADS;
|
||||
|
||||
lws_set_log_level(LLL_ERR | LLL_WARN | LLL_NOTICE | LLL_USER
|
||||
/* | LLL_INFO */ /* | LLL_DEBUG */, NULL);
|
||||
|
||||
lwsl_user("LWS minimal http server SMP | visit http://localhost:7681\n");
|
||||
|
||||
context = lws_create_context(&info);
|
||||
if (!context) {
|
||||
lwsl_err("lws init failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
lwsl_notice(" Service threads: %d\n", lws_get_count_threads(context));
|
||||
|
||||
/* start all the service threads */
|
||||
|
||||
for (n = 0; n < lws_get_count_threads(context); n++)
|
||||
if (pthread_create(&pthread_service[n], NULL, thread_service,
|
||||
(void *)(lws_intptr_t)n))
|
||||
lwsl_err("Failed to start service thread\n");
|
||||
|
||||
/* wait for all the service threads to exit */
|
||||
|
||||
while ((--n) >= 0)
|
||||
pthread_join(pthread_service[n], &retval);
|
||||
|
||||
lws_context_destroy(context);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,10 +1,12 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(lws-minimal-http-server C)
|
||||
|
||||
set(SAMP lws-minimal-http-server)
|
||||
set(SRCS minimal-http-server.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)
|
||||
|
||||
|
|
|
@ -12,5 +12,9 @@ else()
|
|||
message(FATAL_ERROR "LWS need to have been built for extensions")
|
||||
endif()
|
||||
|
||||
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)
|
||||
|
|
|
@ -53,79 +53,37 @@ static const char * const redundant_string =
|
|||
/* this is how much we will send each time the connection is writable */
|
||||
#define MESSAGE_CHUNK_SIZE (1 * 1024)
|
||||
|
||||
|
||||
/* one of these is created for each client connecting to us */
|
||||
|
||||
struct per_session_data__minimal_pmd_bulk {
|
||||
struct per_session_data__minimal_pmd_bulk *pss_list;
|
||||
struct lws *wsi;
|
||||
int position; /* byte position we got up to sending the message */
|
||||
uint64_t rng;
|
||||
};
|
||||
|
||||
/* one of these is created for each vhost our protocol is used with */
|
||||
|
||||
struct per_vhost_data__minimal_pmd_bulk {
|
||||
struct lws_context *context;
|
||||
struct lws_vhost *vhost;
|
||||
const struct lws_protocols *protocol;
|
||||
|
||||
/* linked-list of live pss */
|
||||
struct per_session_data__minimal_pmd_bulk *pss_list;
|
||||
};
|
||||
|
||||
static int
|
||||
callback_minimal_pmd_bulk(struct lws *wsi, enum lws_callback_reasons reason,
|
||||
void *user, void *in, size_t len)
|
||||
{
|
||||
struct per_session_data__minimal_pmd_bulk **ppss, *pss =
|
||||
struct per_session_data__minimal_pmd_bulk *pss =
|
||||
(struct per_session_data__minimal_pmd_bulk *)user;
|
||||
struct per_vhost_data__minimal_pmd_bulk *vhd =
|
||||
(struct per_vhost_data__minimal_pmd_bulk *)
|
||||
lws_protocol_vh_priv_get(lws_get_vhost(wsi),
|
||||
lws_get_protocol(wsi));
|
||||
uint8_t buf[LWS_PRE + MESSAGE_CHUNK_SIZE], *p;
|
||||
uint32_t oldest;
|
||||
int n, m, s, msg_flag = LWS_WRITE_CONTINUATION;
|
||||
int n, m, msg_flag;
|
||||
|
||||
switch (reason) {
|
||||
case LWS_CALLBACK_PROTOCOL_INIT:
|
||||
vhd = lws_protocol_vh_priv_zalloc(lws_get_vhost(wsi),
|
||||
lws_get_protocol(wsi),
|
||||
sizeof(struct per_vhost_data__minimal_pmd_bulk));
|
||||
vhd->context = lws_get_context(wsi);
|
||||
vhd->protocol = lws_get_protocol(wsi);
|
||||
vhd->vhost = lws_get_vhost(wsi);
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_ESTABLISHED:
|
||||
/* add ourselves to the list of live pss held in the vhd */
|
||||
pss->pss_list = vhd->pss_list;
|
||||
vhd->pss_list = pss;
|
||||
pss->wsi = wsi;
|
||||
pss->position = 0;
|
||||
pss->rng = 4;
|
||||
lws_callback_on_writable(wsi);
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_CLOSED:
|
||||
/* remove our closing pss from the list of live pss */
|
||||
lws_start_foreach_llp(struct per_session_data__minimal_pmd_bulk **,
|
||||
ppss, vhd->pss_list) {
|
||||
if (*ppss == pss) {
|
||||
*ppss = pss->pss_list;
|
||||
break;
|
||||
}
|
||||
} lws_end_foreach_llp(ppss, pss_list);
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_SERVER_WRITEABLE:
|
||||
|
||||
if (pss->position == MESSAGE_SIZE)
|
||||
break;
|
||||
|
||||
if (pss->position == 0)
|
||||
if (!pss->position)
|
||||
msg_flag = LWS_WRITE_TEXT;
|
||||
else
|
||||
msg_flag = LWS_WRITE_CONTINUATION;
|
||||
|
||||
/* fill up one chunk's worth of message content */
|
||||
|
||||
|
@ -162,18 +120,14 @@ callback_minimal_pmd_bulk(struct lws *wsi, enum lws_callback_reasons reason,
|
|||
|
||||
n = lws_ptr_diff(p, &buf[LWS_PRE]);
|
||||
m = lws_write(wsi, &buf[LWS_PRE], n, msg_flag);
|
||||
lwsl_notice("write done\n");
|
||||
if (m < n) {
|
||||
lwsl_err("ERROR %d writing to di socket\n", n);
|
||||
lwsl_err("ERROR %d writing ws\n", n);
|
||||
return -1;
|
||||
}
|
||||
if (pss->position != MESSAGE_SIZE) /* if more to do... */
|
||||
lws_callback_on_writable(wsi);
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_RECEIVE:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,11 @@ set(CMAKE_REQUIRED_LIBRARIES websockets)
|
|||
CHECK_FUNCTION_EXISTS(lws_extension_callback_pm_deflate HAVE_PMD)
|
||||
if (HAVE_PMD)
|
||||
else()
|
||||
message(FATAL_ERROR "LWS need to have been built for extensions")
|
||||
message(FATAL_ERROR "LWS needs to have been built for extensions")
|
||||
endif()
|
||||
|
||||
if (UNIX)
|
||||
set(CMAKE_C_FLAGS "-Wall -Wsign-compare -Wignored-qualifiers -Wtype-limits -Wuninitialized -Werror -Wundef ${CMAKE_C_FLAGS}" )
|
||||
endif()
|
||||
|
||||
add_executable(${SAMP} ${SRCS})
|
||||
|
|
|
@ -63,13 +63,12 @@ static int
|
|||
callback_minimal(struct lws *wsi, enum lws_callback_reasons reason,
|
||||
void *user, void *in, size_t len)
|
||||
{
|
||||
struct per_session_data__minimal **ppss, *pss =
|
||||
struct per_session_data__minimal *pss =
|
||||
(struct per_session_data__minimal *)user;
|
||||
struct per_vhost_data__minimal *vhd =
|
||||
(struct per_vhost_data__minimal *)
|
||||
lws_protocol_vh_priv_get(lws_get_vhost(wsi),
|
||||
lws_get_protocol(wsi));
|
||||
uint32_t oldest;
|
||||
int n, m;
|
||||
|
||||
switch (reason) {
|
||||
|
@ -111,7 +110,7 @@ callback_minimal(struct lws *wsi, enum lws_callback_reasons reason,
|
|||
/* notice we allowed for LWS_PRE in the payload already */
|
||||
m = lws_write(wsi, vhd->amsg.payload + LWS_PRE, vhd->amsg.len,
|
||||
LWS_WRITE_TEXT);
|
||||
if (m < vhd->amsg.len) {
|
||||
if (m < (int)vhd->amsg.len) {
|
||||
lwsl_err("ERROR %d writing to di socket\n", n);
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(lws-minimal-ws-server C)
|
||||
|
||||
set(SAMP lws-minimal-ws-server)
|
||||
set(SRCS minimal-ws-server.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)
|
||||
|
|
|
@ -61,7 +61,7 @@ static int
|
|||
callback_minimal(struct lws *wsi, enum lws_callback_reasons reason,
|
||||
void *user, void *in, size_t len)
|
||||
{
|
||||
struct per_session_data__minimal **ppss, *pss =
|
||||
struct per_session_data__minimal *pss =
|
||||
(struct per_session_data__minimal *)user;
|
||||
struct per_vhost_data__minimal *vhd =
|
||||
(struct per_vhost_data__minimal *)
|
||||
|
@ -116,7 +116,7 @@ callback_minimal(struct lws *wsi, enum lws_callback_reasons reason,
|
|||
/* notice we allowed for LWS_PRE in the payload already */
|
||||
m = lws_write(wsi, pmsg->payload + LWS_PRE, pmsg->len,
|
||||
LWS_WRITE_TEXT);
|
||||
if (m < pmsg->len) {
|
||||
if (m < (int)pmsg->len) {
|
||||
lwsl_err("ERROR %d writing to di socket\n", n);
|
||||
return -1;
|
||||
}
|
||||
|
@ -145,7 +145,7 @@ callback_minimal(struct lws *wsi, enum lws_callback_reasons reason,
|
|||
/* more to do? */
|
||||
if (lws_ring_get_element(vhd->ring, &pss->tail))
|
||||
/* come back as soon as we can write more */
|
||||
lws_callback_on_writable((*ppss)->wsi);
|
||||
lws_callback_on_writable(pss->wsi);
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_RECEIVE:
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(lws-minimal-ws-server C)
|
||||
|
||||
set(SAMP lws-minimal-ws-server)
|
||||
set(SRCS minimal-ws-server.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)
|
||||
|
|
|
@ -63,13 +63,12 @@ static int
|
|||
callback_minimal(struct lws *wsi, enum lws_callback_reasons reason,
|
||||
void *user, void *in, size_t len)
|
||||
{
|
||||
struct per_session_data__minimal **ppss, *pss =
|
||||
struct per_session_data__minimal *pss =
|
||||
(struct per_session_data__minimal *)user;
|
||||
struct per_vhost_data__minimal *vhd =
|
||||
(struct per_vhost_data__minimal *)
|
||||
lws_protocol_vh_priv_get(lws_get_vhost(wsi),
|
||||
lws_get_protocol(wsi));
|
||||
uint32_t oldest;
|
||||
int n, m;
|
||||
|
||||
switch (reason) {
|
||||
|
@ -111,8 +110,8 @@ callback_minimal(struct lws *wsi, enum lws_callback_reasons reason,
|
|||
/* notice we allowed for LWS_PRE in the payload already */
|
||||
m = lws_write(wsi, vhd->amsg.payload + LWS_PRE, vhd->amsg.len,
|
||||
LWS_WRITE_TEXT);
|
||||
if (m < vhd->amsg.len) {
|
||||
lwsl_err("ERROR %d writing to di socket\n", n);
|
||||
if (m < (int)vhd->amsg.len) {
|
||||
lwsl_err("ERROR %d writing to ws\n", n);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -219,10 +219,10 @@ int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user,
|
|||
WSI_TOKEN_HTTP_URI_ARGS, n) > 0) {
|
||||
lwsl_notice("URI Arg %d: %s\n", ++n, buf);
|
||||
}
|
||||
}
|
||||
|
||||
if (lws_get_peer_simple(wsi, buf, sizeof(buf)))
|
||||
lwsl_info("HTTP connect from %s\n", buf);
|
||||
if (lws_get_peer_simple(wsi, buf, sizeof(buf)))
|
||||
lwsl_info("HTTP connect from %s\n", buf);
|
||||
}
|
||||
|
||||
if (len < 1) {
|
||||
lws_return_http_status(wsi,
|
||||
|
|
|
@ -300,7 +300,7 @@ int main(int argc, char **argv)
|
|||
#endif
|
||||
|
||||
/* tell the library what debug level to emit and to send it to syslog */
|
||||
lws_set_log_level(debug_level, lwsl_emit_syslog);
|
||||
lws_set_log_level(debug_level, NULL);
|
||||
lwsl_notice("libwebsockets test server pthreads - license LGPL2.1+SLE\n");
|
||||
lwsl_notice("(C) Copyright 2010-2018 Andy Green <andy@warmcat.com>\n");
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue