mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
minimal-examples: http server
This commit is contained in:
parent
d39ecd814a
commit
cce9711653
25 changed files with 1090 additions and 3 deletions
|
@ -1276,7 +1276,7 @@ LWS_EXTERN void lws_feature_status_libuv(struct lws_context_creation_info *info)
|
|||
#define LWS_LIBUV_ENABLED(context) (0)
|
||||
#if LWS_POSIX && !defined(LWS_WITH_ESP32)
|
||||
#define lws_feature_status_libuv(_a) \
|
||||
lwsl_notice("libuv support not compiled in\n")
|
||||
lwsl_info("libuv support not compiled in\n")
|
||||
#else
|
||||
#define lws_feature_status_libuv(_a)
|
||||
#endif
|
||||
|
@ -1307,7 +1307,7 @@ LWS_EXTERN void lws_feature_status_libevent(struct lws_context_creation_info *in
|
|||
#define LWS_LIBEVENT_ENABLED(context) (0)
|
||||
#if LWS_POSIX && !defined(LWS_WITH_ESP32)
|
||||
#define lws_feature_status_libevent(_a) \
|
||||
lwsl_notice("libevent support not compiled in\n")
|
||||
lwsl_info("libevent support not compiled in\n")
|
||||
#else
|
||||
#define lws_feature_status_libevent(_a)
|
||||
#endif
|
||||
|
|
|
@ -1491,7 +1491,7 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd,
|
|||
lws_handle_POLLOUT_event(wsi, pollfd)) {
|
||||
if (wsi->state == LWSS_RETURNED_CLOSE_ALREADY)
|
||||
wsi->state = LWSS_FLUSHING_SEND_BEFORE_CLOSE;
|
||||
lwsl_notice("lws_service_fd: closing\n");
|
||||
// lwsl_notice("lws_service_fd: closing\n");
|
||||
/* the write failed... it's had it */
|
||||
wsi->socket_is_permanently_unusable = 1;
|
||||
goto close_and_handled;
|
||||
|
|
10
minimal-examples/minimal-http-client/CMakeLists.txt
Normal file
10
minimal-examples/minimal-http-client/CMakeLists.txt
Normal file
|
@ -0,0 +1,10 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(lws-minimal-http-client C)
|
||||
|
||||
set(SAMP lws-minimal-http-client)
|
||||
set(SRCS minimal-http-client.c)
|
||||
|
||||
add_executable(${SAMP} ${SRCS})
|
||||
target_link_libraries(${SAMP} -lwebsockets)
|
||||
|
52
minimal-examples/minimal-http-client/README.md
Normal file
52
minimal-examples/minimal-http-client/README.md
Normal file
|
@ -0,0 +1,52 @@
|
|||
# lws minimal http client
|
||||
|
||||
## build
|
||||
|
||||
```
|
||||
$ cmake . && make
|
||||
```
|
||||
|
||||
## usage
|
||||
|
||||
The application goes to https://warmcat.com and receives the page data.
|
||||
|
||||
```
|
||||
$ ./lws-minimal-http-client
|
||||
[2018/03/04 14:43:20:8562] USER: LWS minimal http client
|
||||
[2018/03/04 14:43:20:8571] NOTICE: Creating Vhost 'default' port -1, 1 protocols, IPv6 on
|
||||
[2018/03/04 14:43:20:8616] NOTICE: created client ssl context for default
|
||||
[2018/03/04 14:43:20:8617] NOTICE: lws_client_connect_2: 0x1814dc0: address warmcat.com
|
||||
[2018/03/04 14:43:21:1496] NOTICE: lws_client_connect_2: 0x1814dc0: address warmcat.com
|
||||
[2018/03/04 14:43:22:0154] NOTICE: lws_client_interpret_server_handshake: incoming content length 26520
|
||||
[2018/03/04 14:43:22:0154] NOTICE: lws_client_interpret_server_handshake: client connection up
|
||||
[2018/03/04 14:43:22:0169] USER: RECEIVE_CLIENT_HTTP_READ: read 1024
|
||||
[2018/03/04 14:43:22:0169] USER: RECEIVE_CLIENT_HTTP_READ: read 1024
|
||||
[2018/03/04 14:43:22:0169] USER: RECEIVE_CLIENT_HTTP_READ: read 1024
|
||||
[2018/03/04 14:43:22:0169] USER: RECEIVE_CLIENT_HTTP_READ: read 1015
|
||||
[2018/03/04 14:43:22:0174] USER: RECEIVE_CLIENT_HTTP_READ: read 1024
|
||||
[2018/03/04 14:43:22:0174] USER: RECEIVE_CLIENT_HTTP_READ: read 1024
|
||||
[2018/03/04 14:43:22:0174] USER: RECEIVE_CLIENT_HTTP_READ: read 1024
|
||||
[2018/03/04 14:43:22:0174] USER: RECEIVE_CLIENT_HTTP_READ: read 1015
|
||||
[2018/03/04 14:43:22:0179] USER: RECEIVE_CLIENT_HTTP_READ: read 1024
|
||||
[2018/03/04 14:43:22:0179] USER: RECEIVE_CLIENT_HTTP_READ: read 1024
|
||||
[2018/03/04 14:43:22:0179] USER: RECEIVE_CLIENT_HTTP_READ: read 1024
|
||||
[2018/03/04 14:43:22:0179] USER: RECEIVE_CLIENT_HTTP_READ: read 1015
|
||||
[2018/03/04 14:43:22:3010] USER: RECEIVE_CLIENT_HTTP_READ: read 1024
|
||||
[2018/03/04 14:43:22:3010] USER: RECEIVE_CLIENT_HTTP_READ: read 1024
|
||||
[2018/03/04 14:43:22:3010] USER: RECEIVE_CLIENT_HTTP_READ: read 1024
|
||||
[2018/03/04 14:43:22:3010] USER: RECEIVE_CLIENT_HTTP_READ: read 1015
|
||||
[2018/03/04 14:43:22:3015] USER: RECEIVE_CLIENT_HTTP_READ: read 1024
|
||||
[2018/03/04 14:43:22:3015] USER: RECEIVE_CLIENT_HTTP_READ: read 1024
|
||||
[2018/03/04 14:43:22:3015] USER: RECEIVE_CLIENT_HTTP_READ: read 1024
|
||||
[2018/03/04 14:43:22:3015] USER: RECEIVE_CLIENT_HTTP_READ: read 1015
|
||||
[2018/03/04 14:43:22:3020] USER: RECEIVE_CLIENT_HTTP_READ: read 1024
|
||||
[2018/03/04 14:43:22:3020] USER: RECEIVE_CLIENT_HTTP_READ: read 1024
|
||||
[2018/03/04 14:43:22:3020] USER: RECEIVE_CLIENT_HTTP_READ: read 1024
|
||||
[2018/03/04 14:43:22:3020] USER: RECEIVE_CLIENT_HTTP_READ: read 1015
|
||||
[2018/03/04 14:43:22:3022] USER: RECEIVE_CLIENT_HTTP_READ: read 1024
|
||||
[2018/03/04 14:43:22:3022] USER: RECEIVE_CLIENT_HTTP_READ: read 974
|
||||
[2018/03/04 14:43:22:3022] NOTICE: lws_http_client_read: transaction completed says -1
|
||||
[2018/03/04 14:43:23:3042] USER: Completed
|
||||
```
|
||||
|
||||
|
123
minimal-examples/minimal-http-client/minimal-http-client.c
Normal file
123
minimal-examples/minimal-http-client/minimal-http-client.c
Normal file
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* lws-minimal-http-client
|
||||
*
|
||||
* 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 the a minimal http client using lws.
|
||||
*
|
||||
* It visits https://warmcat.com/ and receives the html page there. You
|
||||
* can dump the page data by changing the #if 0 below.
|
||||
*/
|
||||
|
||||
#include <libwebsockets.h>
|
||||
#include <string.h>
|
||||
|
||||
static struct lws *client_wsi;
|
||||
|
||||
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] ... */
|
||||
case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
|
||||
lwsl_err("CLIENT_CONNECTION_ERROR: %s\n",
|
||||
in ? (char *)in : "(null)");
|
||||
client_wsi = NULL;
|
||||
break;
|
||||
|
||||
/* chunks of chunked content, with header removed */
|
||||
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('.');
|
||||
#endif
|
||||
return 0; /* don't passthru */
|
||||
|
||||
/* uninterpreted http content */
|
||||
case LWS_CALLBACK_RECEIVE_CLIENT_HTTP:
|
||||
{
|
||||
char buffer[1024 + LWS_PRE];
|
||||
char *px = buffer + LWS_PRE;
|
||||
int lenx = sizeof(buffer) - LWS_PRE;
|
||||
|
||||
if (lws_http_client_read(wsi, &px, &lenx) < 0)
|
||||
return -1;
|
||||
}
|
||||
return 0; /* don't passthru */
|
||||
|
||||
case LWS_CALLBACK_COMPLETED_CLIENT_HTTP:
|
||||
client_wsi = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return lws_callback_http_dummy(wsi, reason, user, in, len);
|
||||
}
|
||||
|
||||
static const struct lws_protocols protocols[] = {
|
||||
{
|
||||
"http",
|
||||
callback_http,
|
||||
0,
|
||||
0,
|
||||
},
|
||||
{ NULL, NULL, 0, 0 }
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
lws_set_log_level(LLL_ERR | LLL_WARN | LLL_NOTICE | LLL_USER, NULL);
|
||||
lwsl_user("LWS minimal http 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 = "warmcat.com";
|
||||
i.path = "/";
|
||||
i.host = i.address;
|
||||
i.origin = i.address;
|
||||
i.ssl_connection = 1;
|
||||
i.method = "GET";
|
||||
|
||||
i.protocol = protocols[0].name;
|
||||
i.pwsi = &client_wsi;
|
||||
lws_client_connect_via_info(&i);
|
||||
|
||||
while (n >= 0 && client_wsi)
|
||||
n = lws_service(context, 1000);
|
||||
|
||||
lws_context_destroy(context);
|
||||
lwsl_user("Completed\n");
|
||||
|
||||
return 0;
|
||||
}
|
10
minimal-examples/minimal-http-server/CMakeLists.txt
Normal file
10
minimal-examples/minimal-http-server/CMakeLists.txt
Normal file
|
@ -0,0 +1,10 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(lws-minimal-http-server C)
|
||||
|
||||
set(SAMP lws-minimal-http-server)
|
||||
set(SRCS minimal-http-server.c)
|
||||
|
||||
add_executable(${SAMP} ${SRCS})
|
||||
target_link_libraries(${SAMP} -lwebsockets)
|
||||
|
18
minimal-examples/minimal-http-server/README.md
Normal file
18
minimal-examples/minimal-http-server/README.md
Normal file
|
@ -0,0 +1,18 @@
|
|||
# lws minimal http server
|
||||
|
||||
## build
|
||||
|
||||
```
|
||||
$ cmake . && make
|
||||
```
|
||||
|
||||
## usage
|
||||
|
||||
```
|
||||
$ ./lws-minimal-http-server
|
||||
[2018/03/04 09:30:02:7986] USER: LWS minimal http server | visit http://localhost:7681
|
||||
[2018/03/04 09:30:02:7986] NOTICE: Creating Vhost 'default' port 7681, 1 protocols, IPv6 on
|
||||
```
|
||||
|
||||
Visit http://localhost:7681
|
||||
|
BIN
minimal-examples/minimal-http-server/favicon.ico
Normal file
BIN
minimal-examples/minimal-http-server/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
9
minimal-examples/minimal-http-server/index.html
Normal file
9
minimal-examples/minimal-http-server/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 example</b>.
|
||||
</body>
|
||||
</html>
|
||||
|
BIN
minimal-examples/minimal-http-server/libwebsockets.org-logo.png
Normal file
BIN
minimal-examples/minimal-http-server/libwebsockets.org-logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.9 KiB |
63
minimal-examples/minimal-http-server/minimal-http-server.c
Normal file
63
minimal-examples/minimal-http-server/minimal-http-server.c
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* lws-minimal-http-server
|
||||
*
|
||||
* 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 the most minimal 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
|
||||
*/
|
||||
|
||||
#include <libwebsockets.h>
|
||||
#include <string.h>
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct lws_context_creation_info info;
|
||||
struct lws_context *context;
|
||||
int n = 0;
|
||||
|
||||
memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */
|
||||
info.port = 7681;
|
||||
info.mounts = &mount;
|
||||
|
||||
lws_set_log_level(LLL_ERR | LLL_WARN | LLL_NOTICE | LLL_USER, NULL);
|
||||
lwsl_user("LWS minimal http server | visit http://localhost:7681\n");
|
||||
|
||||
context = lws_create_context(&info);
|
||||
if (!context) {
|
||||
lwsl_err("lws init failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (n >=0)
|
||||
n = lws_service(context, 1000);
|
||||
|
||||
lws_context_destroy(context);
|
||||
|
||||
return 0;
|
||||
}
|
9
minimal-examples/minimal-ws-server-ring/CMakeLists.txt
Normal file
9
minimal-examples/minimal-ws-server-ring/CMakeLists.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(lws-minimal-ws-server C)
|
||||
|
||||
set(SAMP lws-minimal-ws-server)
|
||||
set(SRCS minimal-ws-server.c)
|
||||
|
||||
add_executable(${SAMP} ${SRCS})
|
||||
target_link_libraries(${SAMP} -lwebsockets)
|
21
minimal-examples/minimal-ws-server-ring/README.md
Normal file
21
minimal-examples/minimal-ws-server-ring/README.md
Normal file
|
@ -0,0 +1,21 @@
|
|||
# lws minimal ws server (lws_ring)
|
||||
|
||||
## build
|
||||
|
||||
```
|
||||
$ cmake . && make
|
||||
```
|
||||
|
||||
## usage
|
||||
|
||||
```
|
||||
$ ./lws-minimal-ws-server
|
||||
[2018/03/04 09:30:02:7986] USER: LWS minimal ws server (lws_ring) | visit http://localhost:7681
|
||||
[2018/03/04 09:30:02:7986] NOTICE: Creating Vhost 'default' port 7681, 1 protocols, IPv6 on
|
||||
```
|
||||
|
||||
Visit http://localhost:7681 on multiple browser windows
|
||||
|
||||
Text you type in any browser window is sent to all of them.
|
||||
|
||||
A ringbuffer holds up to 8 lines of text.
|
BIN
minimal-examples/minimal-ws-server-ring/favicon.ico
Normal file
BIN
minimal-examples/minimal-ws-server-ring/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
84
minimal-examples/minimal-ws-server-ring/index.html
Normal file
84
minimal-examples/minimal-ws-server-ring/index.html
Normal file
|
@ -0,0 +1,84 @@
|
|||
<meta charset="UTF-8">
|
||||
<html>
|
||||
<body>
|
||||
|
||||
<img src="libwebsockets.org-logo.png"><br>
|
||||
|
||||
LWS chat <b>minimal ws server example</b>.<br>
|
||||
Chat is sent to all browsers open on this page.
|
||||
<br>
|
||||
<br>
|
||||
<textarea id=r readonly cols=40 rows=10></textarea><br>
|
||||
|
||||
<input type="text" id=m cols=40 rows=1>
|
||||
<button id=b onclick="sendmsg();">Send</button>
|
||||
</body>
|
||||
|
||||
|
||||
<script>
|
||||
function get_appropriate_ws_url(extra_url)
|
||||
{
|
||||
var pcol;
|
||||
var u = document.URL;
|
||||
|
||||
/*
|
||||
* We open the websocket encrypted if this page came on an
|
||||
* https:// url itself, otherwise unencrypted
|
||||
*/
|
||||
|
||||
if (u.substring(0, 5) == "https") {
|
||||
pcol = "wss://";
|
||||
u = u.substr(8);
|
||||
} else {
|
||||
pcol = "ws://";
|
||||
if (u.substring(0, 4) == "http")
|
||||
u = u.substr(7);
|
||||
}
|
||||
|
||||
u = u.split('/');
|
||||
|
||||
/* + "/xxx" bit is for IE10 workaround */
|
||||
|
||||
return pcol + u[0] + "/" + extra_url;
|
||||
}
|
||||
|
||||
function new_ws(urlpath, protocol)
|
||||
{
|
||||
if (typeof MozWebSocket != "undefined")
|
||||
return new MozWebSocket(urlpath, protocol);
|
||||
|
||||
return new WebSocket(urlpath, protocol);
|
||||
}
|
||||
|
||||
ws = new_ws(get_appropriate_ws_url(""), "lws-minimal");
|
||||
try {
|
||||
ws.onopen = function() {
|
||||
document.getElementById("m").disabled = 0;
|
||||
document.getElementById("b").disabled = 0;
|
||||
}
|
||||
|
||||
ws.onmessage =function got_packet(msg) {
|
||||
document.getElementById("r").value =
|
||||
document.getElementById("r").value + msg.data + "\n";
|
||||
document.getElementById("r").scrollTop =
|
||||
document.getElementById("r").scrollHeight;
|
||||
}
|
||||
|
||||
ws.onclose = function(){
|
||||
document.getElementById("m").disabled = 1;
|
||||
document.getElementById("b").disabled = 1;
|
||||
}
|
||||
} catch(exception) {
|
||||
alert('<p>Error' + exception);
|
||||
}
|
||||
|
||||
function sendmsg()
|
||||
{
|
||||
ws.send(document.getElementById("m").value);
|
||||
document.getElementById("m").value = "";
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</html>
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 6.9 KiB |
73
minimal-examples/minimal-ws-server-ring/minimal-ws-server.c
Normal file
73
minimal-examples/minimal-ws-server-ring/minimal-ws-server.c
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* lws-minimal-ws-server
|
||||
*
|
||||
* 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 the most minimal 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
|
||||
*/
|
||||
|
||||
#include <libwebsockets.h>
|
||||
#include <string.h>
|
||||
|
||||
#define LWS_PLUGIN_STATIC
|
||||
#include "protocol_lws_minimal.c"
|
||||
|
||||
static struct lws_protocols protocols[] = {
|
||||
{ "http", lws_callback_http_dummy, 0, 0 },
|
||||
LWS_PLUGIN_PROTOCOL_MINIMAL,
|
||||
{ NULL, NULL, 0, 0 } /* terminator */
|
||||
};
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct lws_context_creation_info info;
|
||||
struct lws_context *context;
|
||||
int n = 0;
|
||||
|
||||
memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */
|
||||
info.port = 7681;
|
||||
info.mounts = &mount;
|
||||
info.protocols = protocols;
|
||||
|
||||
lws_set_log_level(LLL_ERR | LLL_WARN | LLL_NOTICE | LLL_USER, NULL);
|
||||
lwsl_user("LWS minimal ws server (lws_ring) | visit http://localhost:7681\n");
|
||||
|
||||
context = lws_create_context(&info);
|
||||
if (!context) {
|
||||
lwsl_err("lws init failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (n >=0)
|
||||
n = lws_service(context, 1000);
|
||||
|
||||
lws_context_destroy(context);
|
||||
|
||||
return 0;
|
||||
}
|
235
minimal-examples/minimal-ws-server-ring/protocol_lws_minimal.c
Normal file
235
minimal-examples/minimal-ws-server-ring/protocol_lws_minimal.c
Normal file
|
@ -0,0 +1,235 @@
|
|||
/*
|
||||
* ws protocol handler plugin for "lws-minimal"
|
||||
*
|
||||
* Copyright (C) 2010-2018 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* This file is made available under the Creative Commons CC0 1.0
|
||||
* Universal Public Domain Dedication.
|
||||
*
|
||||
* This version uses an lws_ring ringbuffer to cache up to 8 messages at a time,
|
||||
* so it's not so easy to lose messages.
|
||||
*/
|
||||
|
||||
#if !defined (LWS_PLUGIN_STATIC)
|
||||
#define LWS_DLL
|
||||
#define LWS_INTERNAL
|
||||
#include <libwebsockets.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* one of these created for each message */
|
||||
|
||||
struct msg {
|
||||
void *payload; /* is malloc'd */
|
||||
size_t len;
|
||||
};
|
||||
|
||||
/* one of these is created for each client connecting to us */
|
||||
|
||||
struct per_session_data__minimal {
|
||||
struct per_session_data__minimal *pss_list;
|
||||
struct lws *wsi;
|
||||
uint32_t tail;
|
||||
};
|
||||
|
||||
/* one of these is created for each vhost our protocol is used with */
|
||||
|
||||
struct per_vhost_data__minimal {
|
||||
struct lws_context *context;
|
||||
struct lws_vhost *vhost;
|
||||
const struct lws_protocols *protocol;
|
||||
|
||||
struct per_session_data__minimal *pss_list; /* linked-list of live pss*/
|
||||
|
||||
struct lws_ring *ring; /* ringbuffer holding unsent messages */
|
||||
};
|
||||
|
||||
/* destroys the message when everyone has had a copy of it */
|
||||
|
||||
static void
|
||||
__minimal_destroy_message(void *_msg)
|
||||
{
|
||||
struct msg *msg = _msg;
|
||||
|
||||
free(msg->payload);
|
||||
msg->payload = NULL;
|
||||
msg->len = 0;
|
||||
}
|
||||
|
||||
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 *)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));
|
||||
const struct msg *pmsg;
|
||||
struct msg amsg;
|
||||
uint32_t oldest;
|
||||
int n, m;
|
||||
|
||||
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));
|
||||
vhd->context = lws_get_context(wsi);
|
||||
vhd->protocol = lws_get_protocol(wsi);
|
||||
vhd->vhost = lws_get_vhost(wsi);
|
||||
|
||||
vhd->ring = lws_ring_create(sizeof(struct msg), 8,
|
||||
__minimal_destroy_message);
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_PROTOCOL_DESTROY:
|
||||
lws_ring_destroy(vhd->ring);
|
||||
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->tail = lws_ring_get_oldest_tail(vhd->ring);
|
||||
pss->wsi = 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 **,
|
||||
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:
|
||||
pmsg = lws_ring_get_element(vhd->ring, &pss->tail);
|
||||
if (!pmsg)
|
||||
break;
|
||||
|
||||
/* 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) {
|
||||
lwsl_err("ERROR %d writing to di socket\n", n);
|
||||
return -1;
|
||||
}
|
||||
|
||||
n = lws_ring_get_oldest_tail(vhd->ring) == pss->tail;
|
||||
lws_ring_consume(vhd->ring, &pss->tail, NULL, 1);
|
||||
|
||||
if (n) { /* we may have been the oldest tail */
|
||||
n = 0;
|
||||
oldest = pss->tail;
|
||||
lws_start_foreach_llp(
|
||||
struct per_session_data__minimal **,
|
||||
ppss, vhd->pss_list) {
|
||||
m = lws_ring_get_count_waiting_elements(
|
||||
vhd->ring, &(*ppss)->tail);
|
||||
if (m > n) {
|
||||
n = m;
|
||||
oldest = (*ppss)->tail;
|
||||
}
|
||||
} lws_end_foreach_llp(ppss, pss_list);
|
||||
|
||||
/* this will delete any entries behind the new oldest */
|
||||
lws_ring_update_oldest_tail(vhd->ring, oldest);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_RECEIVE:
|
||||
n = (int)lws_ring_get_count_free_elements(vhd->ring);
|
||||
if (!n) {
|
||||
lwsl_user("dropping!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
amsg.len = len;
|
||||
/* notice we over-allocate by LWS_PRE */
|
||||
amsg.payload = malloc(LWS_PRE + len);
|
||||
if (!amsg.payload) {
|
||||
lwsl_user("OOM: dropping\n");
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy((char *)amsg.payload + LWS_PRE, in, len);
|
||||
if (!lws_ring_insert(vhd->ring, &amsg, 1)) {
|
||||
__minimal_destroy_message(&amsg);
|
||||
lwsl_user("dropping!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* let everybody know we want to write something on them
|
||||
* as soon as they are ready
|
||||
*/
|
||||
lws_start_foreach_llp(struct per_session_data__minimal **,
|
||||
ppss, vhd->pss_list) {
|
||||
lws_callback_on_writable((*ppss)->wsi);
|
||||
} lws_end_foreach_llp(ppss, pss_list);
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_TIMER:
|
||||
lwsl_notice("%s: LWS_CALLBACK_TIMER\n", __func__);
|
||||
lws_set_timer(wsi, 3);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define LWS_PLUGIN_PROTOCOL_MINIMAL \
|
||||
{ \
|
||||
"lws-minimal", \
|
||||
callback_minimal, \
|
||||
sizeof(struct per_session_data__minimal), \
|
||||
128, \
|
||||
0, NULL, 0 \
|
||||
}
|
||||
|
||||
#if !defined (LWS_PLUGIN_STATIC)
|
||||
|
||||
/* boilerplate needed if we are built as a dynamic plugin */
|
||||
|
||||
static const struct lws_protocols protocols[] = {
|
||||
LWS_PLUGIN_PROTOCOL_MINIMAL
|
||||
};
|
||||
|
||||
LWS_EXTERN LWS_VISIBLE int
|
||||
init_protocol_minimal(struct lws_context *context,
|
||||
struct lws_plugin_capability *c)
|
||||
{
|
||||
if (c->api_magic != LWS_PLUGIN_API_MAGIC) {
|
||||
lwsl_err("Plugin API %d, library API %d", LWS_PLUGIN_API_MAGIC,
|
||||
c->api_magic);
|
||||
return 1;
|
||||
}
|
||||
|
||||
c->protocols = protocols;
|
||||
c->count_protocols = ARRAY_SIZE(protocols);
|
||||
c->extensions = NULL;
|
||||
c->count_extensions = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
LWS_EXTERN LWS_VISIBLE int
|
||||
destroy_protocol_minimal(struct lws_context *context)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
9
minimal-examples/minimal-ws-server/CMakeLists.txt
Normal file
9
minimal-examples/minimal-ws-server/CMakeLists.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(lws-minimal-ws-server C)
|
||||
|
||||
set(SAMP lws-minimal-ws-server)
|
||||
set(SRCS minimal-ws-server.c)
|
||||
|
||||
add_executable(${SAMP} ${SRCS})
|
||||
target_link_libraries(${SAMP} -lwebsockets)
|
21
minimal-examples/minimal-ws-server/README.md
Normal file
21
minimal-examples/minimal-ws-server/README.md
Normal file
|
@ -0,0 +1,21 @@
|
|||
# lws minimal ws server
|
||||
|
||||
## build
|
||||
|
||||
```
|
||||
$ cmake . && make
|
||||
```
|
||||
|
||||
## usage
|
||||
|
||||
```
|
||||
$ ./lws-minimal-ws-server
|
||||
[2018/03/04 09:30:02:7986] USER: LWS minimal ws server | visit http://localhost:7681
|
||||
[2018/03/04 09:30:02:7986] NOTICE: Creating Vhost 'default' port 7681, 1 protocols, IPv6 on
|
||||
```
|
||||
|
||||
Visit http://localhost:7681 on multiple browser windows
|
||||
|
||||
Text you type in any browser window is sent to all of them.
|
||||
|
||||
For simplicity of this example, only one line of text is cached at the server.
|
BIN
minimal-examples/minimal-ws-server/favicon.ico
Normal file
BIN
minimal-examples/minimal-ws-server/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
83
minimal-examples/minimal-ws-server/index.html
Normal file
83
minimal-examples/minimal-ws-server/index.html
Normal file
|
@ -0,0 +1,83 @@
|
|||
<meta charset="UTF-8">
|
||||
<html>
|
||||
<body>
|
||||
|
||||
<img src="libwebsockets.org-logo.png"><br>
|
||||
|
||||
LWS chat <b>minimal ws server example</b>.<br>
|
||||
Chat is sent to all browsers open on this page.
|
||||
<br>
|
||||
<br>
|
||||
<textarea id=r readonly cols=40 rows=10></textarea><br>
|
||||
<input type="text" id=m cols=40 rows=1>
|
||||
<button id=b onclick="sendmsg();">Send</button>
|
||||
</body>
|
||||
|
||||
|
||||
<script>
|
||||
function get_appropriate_ws_url(extra_url)
|
||||
{
|
||||
var pcol;
|
||||
var u = document.URL;
|
||||
|
||||
/*
|
||||
* We open the websocket encrypted if this page came on an
|
||||
* https:// url itself, otherwise unencrypted
|
||||
*/
|
||||
|
||||
if (u.substring(0, 5) == "https") {
|
||||
pcol = "wss://";
|
||||
u = u.substr(8);
|
||||
} else {
|
||||
pcol = "ws://";
|
||||
if (u.substring(0, 4) == "http")
|
||||
u = u.substr(7);
|
||||
}
|
||||
|
||||
u = u.split('/');
|
||||
|
||||
/* + "/xxx" bit is for IE10 workaround */
|
||||
|
||||
return pcol + u[0] + "/" + extra_url;
|
||||
}
|
||||
|
||||
function new_ws(urlpath, protocol)
|
||||
{
|
||||
if (typeof MozWebSocket != "undefined")
|
||||
return new MozWebSocket(urlpath, protocol);
|
||||
|
||||
return new WebSocket(urlpath, protocol);
|
||||
}
|
||||
|
||||
ws = new_ws(get_appropriate_ws_url(""), "lws-minimal");
|
||||
try {
|
||||
ws.onopen = function() {
|
||||
document.getElementById("m").disabled = 0;
|
||||
document.getElementById("b").disabled = 0;
|
||||
}
|
||||
|
||||
ws.onmessage =function got_packet(msg) {
|
||||
document.getElementById("r").value =
|
||||
document.getElementById("r").value + msg.data + "\n";
|
||||
document.getElementById("r").scrollTop =
|
||||
document.getElementById("r").scrollHeight;
|
||||
}
|
||||
|
||||
ws.onclose = function(){
|
||||
document.getElementById("m").disabled = 1;
|
||||
document.getElementById("b").disabled = 1;
|
||||
}
|
||||
} catch(exception) {
|
||||
alert('<p>Error' + exception);
|
||||
}
|
||||
|
||||
function sendmsg()
|
||||
{
|
||||
ws.send(document.getElementById("m").value);
|
||||
document.getElementById("m").value = "";
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</html>
|
||||
|
BIN
minimal-examples/minimal-ws-server/libwebsockets.org-logo.png
Normal file
BIN
minimal-examples/minimal-ws-server/libwebsockets.org-logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.9 KiB |
73
minimal-examples/minimal-ws-server/minimal-ws-server.c
Normal file
73
minimal-examples/minimal-ws-server/minimal-ws-server.c
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* lws-minimal-ws-server
|
||||
*
|
||||
* 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 the most minimal 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
|
||||
*/
|
||||
|
||||
#include <libwebsockets.h>
|
||||
#include <string.h>
|
||||
|
||||
#define LWS_PLUGIN_STATIC
|
||||
#include "protocol_lws_minimal.c"
|
||||
|
||||
static struct lws_protocols protocols[] = {
|
||||
{ "http", lws_callback_http_dummy, 0, 0 },
|
||||
LWS_PLUGIN_PROTOCOL_MINIMAL,
|
||||
{ NULL, NULL, 0, 0 } /* terminator */
|
||||
};
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct lws_context_creation_info info;
|
||||
struct lws_context *context;
|
||||
int n = 0;
|
||||
|
||||
memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */
|
||||
info.port = 7681;
|
||||
info.mounts = &mount;
|
||||
info.protocols = protocols;
|
||||
|
||||
lws_set_log_level(LLL_ERR | LLL_WARN | LLL_NOTICE | LLL_USER, NULL);
|
||||
lwsl_user("LWS minimal ws server | visit http://localhost:7681\n");
|
||||
|
||||
context = lws_create_context(&info);
|
||||
if (!context) {
|
||||
lwsl_err("lws init failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (n >=0)
|
||||
n = lws_service(context, 1000);
|
||||
|
||||
lws_context_destroy(context);
|
||||
|
||||
return 0;
|
||||
}
|
194
minimal-examples/minimal-ws-server/protocol_lws_minimal.c
Normal file
194
minimal-examples/minimal-ws-server/protocol_lws_minimal.c
Normal file
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
* ws protocol handler plugin for "lws-minimal"
|
||||
*
|
||||
* Copyright (C) 2010-2018 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* This file is made available under the Creative Commons CC0 1.0
|
||||
* Universal Public Domain Dedication.
|
||||
*
|
||||
* This version holds a single message at a time, which may be lost if a new
|
||||
* message comes. See the minimal-ws-server-ring sample for the same thing
|
||||
* but using an lws_ring ringbuffer to hold up to 8 messages at a time.
|
||||
*/
|
||||
|
||||
#if !defined (LWS_PLUGIN_STATIC)
|
||||
#define LWS_DLL
|
||||
#define LWS_INTERNAL
|
||||
#include <libwebsockets.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* one of these created for each message */
|
||||
|
||||
struct msg {
|
||||
void *payload; /* is malloc'd */
|
||||
size_t len;
|
||||
};
|
||||
|
||||
/* one of these is created for each client connecting to us */
|
||||
|
||||
struct per_session_data__minimal {
|
||||
struct per_session_data__minimal *pss_list;
|
||||
struct lws *wsi;
|
||||
int last; /* the last message number we sent */
|
||||
};
|
||||
|
||||
/* one of these is created for each vhost our protocol is used with */
|
||||
|
||||
struct per_vhost_data__minimal {
|
||||
struct lws_context *context;
|
||||
struct lws_vhost *vhost;
|
||||
const struct lws_protocols *protocol;
|
||||
|
||||
struct per_session_data__minimal *pss_list; /* linked-list of live pss*/
|
||||
|
||||
struct msg amsg; /* the one pending message... */
|
||||
int current; /* the current message number we are caching */
|
||||
};
|
||||
|
||||
/* destroys the message when everyone has had a copy of it */
|
||||
|
||||
static void
|
||||
__minimal_destroy_message(void *_msg)
|
||||
{
|
||||
struct msg *msg = _msg;
|
||||
|
||||
free(msg->payload);
|
||||
msg->payload = NULL;
|
||||
msg->len = 0;
|
||||
}
|
||||
|
||||
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 *)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) {
|
||||
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));
|
||||
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->last = vhd->current;
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_CLOSED:
|
||||
/* remove our closing pss from the list of live pss */
|
||||
lws_start_foreach_llp(struct per_session_data__minimal **,
|
||||
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 (!vhd->amsg.payload)
|
||||
break;
|
||||
|
||||
if (pss->last == vhd->current)
|
||||
break;
|
||||
|
||||
/* 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);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pss->last = vhd->current;
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_RECEIVE:
|
||||
if (vhd->amsg.payload)
|
||||
__minimal_destroy_message(&vhd->amsg);
|
||||
|
||||
vhd->amsg.len = len;
|
||||
/* notice we over-allocate by LWS_PRE */
|
||||
vhd->amsg.payload = malloc(LWS_PRE + len);
|
||||
if (!vhd->amsg.payload) {
|
||||
lwsl_user("OOM: dropping\n");
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy((char *)vhd->amsg.payload + LWS_PRE, in, len);
|
||||
vhd->current++;
|
||||
|
||||
/*
|
||||
* let everybody know we want to write something on them
|
||||
* as soon as they are ready
|
||||
*/
|
||||
lws_start_foreach_llp(struct per_session_data__minimal **,
|
||||
ppss, vhd->pss_list) {
|
||||
lws_callback_on_writable((*ppss)->wsi);
|
||||
} lws_end_foreach_llp(ppss, pss_list);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define LWS_PLUGIN_PROTOCOL_MINIMAL \
|
||||
{ \
|
||||
"lws-minimal", \
|
||||
callback_minimal, \
|
||||
sizeof(struct per_session_data__minimal), \
|
||||
128, \
|
||||
0, NULL, 0 \
|
||||
}
|
||||
|
||||
#if !defined (LWS_PLUGIN_STATIC)
|
||||
|
||||
/* boilerplate needed if we are built as a dynamic plugin */
|
||||
|
||||
static const struct lws_protocols protocols[] = {
|
||||
LWS_PLUGIN_PROTOCOL_MINIMAL
|
||||
};
|
||||
|
||||
LWS_EXTERN LWS_VISIBLE int
|
||||
init_protocol_minimal(struct lws_context *context,
|
||||
struct lws_plugin_capability *c)
|
||||
{
|
||||
if (c->api_magic != LWS_PLUGIN_API_MAGIC) {
|
||||
lwsl_err("Plugin API %d, library API %d", LWS_PLUGIN_API_MAGIC,
|
||||
c->api_magic);
|
||||
return 1;
|
||||
}
|
||||
|
||||
c->protocols = protocols;
|
||||
c->count_protocols = ARRAY_SIZE(protocols);
|
||||
c->extensions = NULL;
|
||||
c->count_extensions = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
LWS_EXTERN LWS_VISIBLE int
|
||||
destroy_protocol_minimal(struct lws_context *context)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
Loading…
Add table
Reference in a new issue