mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
minimal-ws-server-pmd-bulk: add echo
This commit is contained in:
parent
de4c1303f5
commit
c8af76c07c
10 changed files with 851 additions and 45 deletions
|
@ -5159,19 +5159,22 @@ lws_rx_flow_allow_all_protocol(const struct lws_context *context,
|
|||
|
||||
/**
|
||||
* lws_remaining_packet_payload() - Bytes to come before "overall"
|
||||
* rx packet is complete
|
||||
* rx fragment is complete
|
||||
* \param wsi: Websocket instance (available from user callback)
|
||||
*
|
||||
* This function is intended to be called from the callback if the
|
||||
* user code is interested in "complete packets" from the client.
|
||||
* libwebsockets just passes through payload as it comes and issues a buffer
|
||||
* additionally when it hits a built-in limit. The LWS_CALLBACK_RECEIVE
|
||||
* callback handler can use this API to find out if the buffer it has just
|
||||
* been given is the last piece of a "complete packet" from the client --
|
||||
* when that is the case lws_remaining_packet_payload() will return
|
||||
* 0.
|
||||
* This tracks how many bytes are left in the current ws fragment, according
|
||||
* to the ws length given in the fragment header.
|
||||
*
|
||||
* Many protocols won't care becuse their packets are always small.
|
||||
* If the message was in a single fragment, and there is no compression, this
|
||||
* is the same as "how much data is left to read for this message".
|
||||
*
|
||||
* However, if the message is being sent in multiple fragments, this will
|
||||
* reflect the unread amount of the current **fragment**, not the message. With
|
||||
* ws, it is legal to not know the length of the message before it completes.
|
||||
*
|
||||
* Additionally if the message is sent via the negotiated permessage-deflate
|
||||
* extension, this number only tells the amount of **compressed** data left to
|
||||
* be read, since that is the only information available at the ws layer.
|
||||
*/
|
||||
LWS_VISIBLE LWS_EXTERN size_t
|
||||
lws_remaining_packet_payload(struct lws *wsi);
|
||||
|
|
|
@ -1749,7 +1749,7 @@ read:
|
|||
eff_buf.token_len);
|
||||
switch (eff_buf.token_len) {
|
||||
case 0:
|
||||
lwsl_notice("%s: zero length read\n",
|
||||
lwsl_info("%s: zero length read\n",
|
||||
__func__);
|
||||
goto close_and_handled;
|
||||
case LWS_SSL_CAPABLE_MORE_SERVICE:
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
|name|demonstrates|
|
||||
---|---
|
||||
minimal-ws-client-pmd-bulk|Client that sends bulk multifragment data to the minimal-ws-server-pmd-bulk example
|
||||
minimal-ws-client-rx|Connects to the dumb-increment-protocol wss server at https://libwebsockets.org and demonstrates receiving ws data
|
||||
minimal-ws-client-tx|Connects to the minimal-ws-broker example as a publisher, demonstrating sending ws data
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
cmake_minimum_required(VERSION 2.8.9)
|
||||
include(CheckCSourceCompiles)
|
||||
|
||||
set(SAMP lws-minimal-ws-client-pmd-bulk)
|
||||
set(SRCS minimal-ws-client-pmd-bulk.c)
|
||||
|
||||
# If we are being built as part of lws, confirm current build config supports
|
||||
# reqconfig, else skip building ourselves.
|
||||
#
|
||||
# If we are being built externally, confirm installed lws was configured to
|
||||
# support reqconfig, else error out with a helpful message about the problem.
|
||||
#
|
||||
MACRO(require_lws_config reqconfig _val result)
|
||||
|
||||
if (DEFINED ${reqconfig})
|
||||
if (${reqconfig})
|
||||
set (rq 1)
|
||||
else()
|
||||
set (rq 0)
|
||||
endif()
|
||||
else()
|
||||
set(rq 0)
|
||||
endif()
|
||||
|
||||
if (${_val} EQUAL ${rq})
|
||||
set(SAME 1)
|
||||
else()
|
||||
set(SAME 0)
|
||||
endif()
|
||||
|
||||
if (LWS_WITH_MINIMAL_EXAMPLES AND NOT ${SAME})
|
||||
if (${_val})
|
||||
message("${SAMP}: skipping as lws being built without ${reqconfig}")
|
||||
else()
|
||||
message("${SAMP}: skipping as lws built with ${reqconfig}")
|
||||
endif()
|
||||
set(${result} 0)
|
||||
else()
|
||||
if (LWS_WITH_MINIMAL_EXAMPLES)
|
||||
set(MET ${SAME})
|
||||
else()
|
||||
CHECK_C_SOURCE_COMPILES("#include <libwebsockets.h>\nint main(void) {\n#if defined(${reqconfig})\n return 0;\n#else\n fail;\n#endif\n return 0;\n}\n" HAS_${reqconfig})
|
||||
if (NOT DEFINED HAS_${reqconfig} OR NOT HAS_${reqconfig})
|
||||
set(HAS_${reqconfig} 0)
|
||||
else()
|
||||
set(HAS_${reqconfig} 1)
|
||||
endif()
|
||||
if ((HAS_${reqconfig} AND ${_val}) OR (NOT HAS_${reqconfig} AND NOT ${_val}))
|
||||
set(MET 1)
|
||||
else()
|
||||
set(MET 0)
|
||||
endif()
|
||||
endif()
|
||||
if (NOT MET)
|
||||
if (${_val})
|
||||
message(FATAL_ERROR "This project requires lws must have been configured with ${reqconfig}")
|
||||
else()
|
||||
message(FATAL_ERROR "Lws configuration of ${reqconfig} is incompatible with this project")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
endif()
|
||||
ENDMACRO()
|
||||
|
||||
set(requirements 1)
|
||||
require_lws_config(LWS_WITHOUT_SERVER 0 requirements)
|
||||
require_lws_config(LWS_WITHOUT_EXTENSIONS 0 requirements)
|
||||
|
||||
if (requirements)
|
||||
add_executable(${SAMP} ${SRCS})
|
||||
|
||||
if (websockets_shared)
|
||||
target_link_libraries(${SAMP} websockets_shared)
|
||||
add_dependencies(${SAMP} websockets_shared)
|
||||
else()
|
||||
target_link_libraries(${SAMP} websockets)
|
||||
endif()
|
||||
endif()
|
164
minimal-examples/ws-client/minimal-ws-client-pmd-bulk/README.md
Normal file
164
minimal-examples/ws-client/minimal-ws-client-pmd-bulk/README.md
Normal file
|
@ -0,0 +1,164 @@
|
|||
# lws minimal ws client + permessage-deflate for bulk traffic
|
||||
|
||||
This example opens a client connection to localhost:7681 where it
|
||||
expects to find minimal-ws-server-pmd-bulk running.
|
||||
|
||||
It sends and receives a large, multifragment message, and then exits.
|
||||
|
||||
## build
|
||||
|
||||
```
|
||||
$ cmake . && make
|
||||
```
|
||||
|
||||
## usage
|
||||
|
||||
Both the server and client side must use the same options
|
||||
|
||||
- `-n` disable permessage-deflate extension
|
||||
- `-c` send compressible text instead of uncompressible binary data
|
||||
|
||||
```
|
||||
$ ./lws-minimal-ws-client-pmd-bulk
|
||||
[2018/04/05 12:08:58:9120] USER: LWS minimal ws client + permessage-deflate + multifragment bulk message
|
||||
[2018/04/05 12:08:58:9120] USER: ./lws-minimal-ws-client-pmd-bulk [-n (no exts)] [-c (compressible)]
|
||||
[2018/04/05 12:08:58:9120] NOTICE: Creating Vhost 'default' (serving disabled), 2 protocols, IPv6 on
|
||||
[2018/04/05 12:08:59:9139] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9139] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9139] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9139] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9139] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9140] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9140] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9140] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9140] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9140] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9140] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9141] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9141] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9141] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9142] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9142] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9142] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9142] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9142] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9142] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9143] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9143] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9143] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9143] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9143] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9143] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9144] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9144] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9144] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9144] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9144] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9144] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9145] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9145] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9145] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9145] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9146] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9146] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9146] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9146] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9146] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9146] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9147] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9147] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9147] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9147] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9147] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9148] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9148] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9148] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9148] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9148] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9148] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9149] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9149] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9149] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9149] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9149] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9149] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9150] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9150] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9150] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9150] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9150] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9150] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9151] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9151] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9151] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9151] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9152] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9152] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9152] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9152] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9152] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9152] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9153] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9153] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9153] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9153] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9153] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9153] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9154] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9154] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9154] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9154] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9154] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9154] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9155] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9155] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9155] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9155] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9155] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9155] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9156] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9156] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9156] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9156] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9157] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9157] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9157] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9157] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9157] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9158] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9158] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9158] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9158] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9158] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9158] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9159] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9159] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9159] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9159] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9159] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9159] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9160] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9160] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9160] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9160] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9160] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9160] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9161] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9161] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9161] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9161] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9161] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9161] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9162] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9162] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9162] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9162] USER: LWS_CALLBACK_CLIENT_RECEIVE: 1024 (rpp 0, last 0)
|
||||
[2018/04/05 12:08:59:9162] USER: LWS_CALLBACK_CLIENT_RECEIVE: 580 (rpp 0, last 1)
|
||||
[2018/04/05 12:08:59:9180] USER: Completed OK
|
||||
```
|
||||
|
||||
Visit http://localhost:7681 in your browser
|
||||
|
||||
One or another kind of bulk ws transfer is made to the browser.
|
||||
|
||||
The ws connection is made via permessage-deflate extension.
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
* lws-minimal-ws-client-pmd-bulk
|
||||
*
|
||||
* 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 ws client that sends bulk data in multiple
|
||||
* ws fragments, in a way compatible with per-message deflate.
|
||||
*
|
||||
* It shows how to send huge messages without needing a lot of memory.
|
||||
*
|
||||
* Build and start the minimal-examples/ws-server/minmal-ws-server-pmd-bulk
|
||||
* example first. Running this sends a large message to the server and
|
||||
* exits.
|
||||
*
|
||||
* If you give both sides the -n commandline option, it disables permessage-
|
||||
* deflate compression extension.
|
||||
*/
|
||||
|
||||
#include <libwebsockets.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#define LWS_PLUGIN_STATIC
|
||||
#include "protocol_lws_minimal_pmd_bulk.c"
|
||||
|
||||
static struct lws_protocols protocols[] = {
|
||||
{ "http", lws_callback_http_dummy, 0, 0 },
|
||||
LWS_PLUGIN_PROTOCOL_MINIMAL_PMD_BULK,
|
||||
{ NULL, NULL, 0, 0 } /* terminator */
|
||||
};
|
||||
|
||||
static int interrupted, options;
|
||||
|
||||
/* pass pointers to shared vars to the protocol */
|
||||
|
||||
static const struct lws_protocol_vhost_options pvo_options = {
|
||||
NULL,
|
||||
NULL,
|
||||
"options", /* pvo name */
|
||||
(void *)&options /* pvo value */
|
||||
};
|
||||
|
||||
static const struct lws_protocol_vhost_options pvo_interrupted = {
|
||||
&pvo_options,
|
||||
NULL,
|
||||
"interrupted", /* pvo name */
|
||||
(void *)&interrupted /* pvo value */
|
||||
};
|
||||
|
||||
static const struct lws_protocol_vhost_options pvo = {
|
||||
NULL, /* "next" pvo linked-list */
|
||||
&pvo_interrupted, /* "child" pvo linked-list */
|
||||
"lws-minimal-pmd-bulk", /* protocol name we belong to on this vhost */
|
||||
"" /* ignored */
|
||||
};
|
||||
static const struct lws_extension extensions[] = {
|
||||
{
|
||||
"permessage-deflate",
|
||||
lws_extension_callback_pm_deflate,
|
||||
"permessage-deflate"
|
||||
"; client_no_context_takeover"
|
||||
"; client_max_window_bits"
|
||||
},
|
||||
{ NULL, NULL, NULL /* terminator */ }
|
||||
};
|
||||
|
||||
void sigint_handler(int sig)
|
||||
{
|
||||
interrupted = 1;
|
||||
}
|
||||
|
||||
static int findswitch(int argc, char **argv, const char *val)
|
||||
{
|
||||
while (--argc > 0) {
|
||||
if (!strcmp(argv[argc], val))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct lws_context_creation_info info;
|
||||
struct lws_context *context;
|
||||
int n = 0;
|
||||
|
||||
signal(SIGINT, sigint_handler);
|
||||
|
||||
memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */
|
||||
info.port = CONTEXT_PORT_NO_LISTEN;
|
||||
info.protocols = protocols;
|
||||
info.pvo = &pvo;
|
||||
if (!findswitch(argc, argv, "-n"))
|
||||
info.extensions = extensions;
|
||||
info.pt_serv_buf_size = 32 * 1024;
|
||||
|
||||
if (!findswitch(argc, argv, "-c"))
|
||||
options |= 1;
|
||||
|
||||
lws_set_log_level(LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE
|
||||
/* for LLL_ verbosity above NOTICE to be built into lws,
|
||||
* lws must have been configured and built with
|
||||
* -DCMAKE_BUILD_TYPE=DEBUG instead of =RELEASE */
|
||||
/* | LLL_INFO */ /* | LLL_PARSER */ /* | LLL_HEADER */
|
||||
/* | LLL_EXT */ /* | LLL_CLIENT */ /* | LLL_LATENCY */
|
||||
/* | LLL_DEBUG */, NULL);
|
||||
|
||||
lwsl_user("LWS minimal ws client + permessage-deflate + multifragment bulk message\n");
|
||||
lwsl_user(" %s [-n (no exts)] [-c (compressible)]\n", argv[0]);
|
||||
context = lws_create_context(&info);
|
||||
if (!context) {
|
||||
lwsl_err("lws init failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (n >= 0 && !interrupted)
|
||||
n = lws_service(context, 1000);
|
||||
|
||||
lws_context_destroy(context);
|
||||
|
||||
lwsl_user("Completed %s\n", interrupted == 2 ? "OK" : "failed");
|
||||
|
||||
return interrupted != 2;
|
||||
}
|
|
@ -0,0 +1,319 @@
|
|||
/*
|
||||
* ws protocol handler plugin for "lws-minimal-pmd-bulk"
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* The protocol shows how to send and receive bulk messages over a ws connection
|
||||
* that optionally may have the permessage-deflate extension negotiated on it.
|
||||
*/
|
||||
|
||||
#if !defined (LWS_PLUGIN_STATIC)
|
||||
#define LWS_DLL
|
||||
#define LWS_INTERNAL
|
||||
#include <libwebsockets.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* We will produce a large ws message either from this text repeated many times,
|
||||
* or from 0x40 + a 6-bit pseudorandom number
|
||||
*/
|
||||
|
||||
static const char * const redundant_string =
|
||||
"No one would have believed in the last years of the nineteenth "
|
||||
"century that this world was being watched keenly and closely by "
|
||||
"intelligences greater than man's and yet as mortal as his own; that as "
|
||||
"men busied themselves about their various concerns they were "
|
||||
"scrutinised and studied, perhaps almost as narrowly as a man with a "
|
||||
"microscope might scrutinise the transient creatures that swarm and "
|
||||
"multiply in a drop of water. With infinite complacency men went to "
|
||||
"and fro over this globe about their little affairs, serene in their "
|
||||
"assurance of their empire over matter. It is possible that the "
|
||||
"infusoria under the microscope do the same. No one gave a thought to "
|
||||
"the older worlds of space as sources of human danger, or thought of "
|
||||
"them only to dismiss the idea of life upon them as impossible or "
|
||||
"improbable. It is curious to recall some of the mental habits of "
|
||||
"those departed days. At most terrestrial men fancied there might be "
|
||||
"other men upon Mars, perhaps inferior to themselves and ready to "
|
||||
"welcome a missionary enterprise. Yet across the gulf of space, minds "
|
||||
"that are to our minds as ours are to those of the beasts that perish, "
|
||||
"intellects vast and cool and unsympathetic, regarded this earth with "
|
||||
"envious eyes, and slowly and surely drew their plans against us. And "
|
||||
"early in the twentieth century came the great disillusionment. "
|
||||
;
|
||||
|
||||
/* this reflects the length of the string above */
|
||||
#define REPEAT_STRING_LEN 1337
|
||||
/* this is the total size of the ws message we will send */
|
||||
#define MESSAGE_SIZE (100 * REPEAT_STRING_LEN)
|
||||
/* 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 {
|
||||
int position_tx, position_rx;
|
||||
uint64_t rng_rx, rng_tx;
|
||||
};
|
||||
|
||||
struct vhd_minimal_pmd_bulk {
|
||||
struct lws_context *context;
|
||||
struct lws_vhost *vhost;
|
||||
struct lws *client_wsi;
|
||||
|
||||
int *interrupted;
|
||||
int *options;
|
||||
};
|
||||
|
||||
static uint64_t rng(uint64_t *r)
|
||||
{
|
||||
*r ^= *r << 21;
|
||||
*r ^= *r >> 35;
|
||||
*r ^= *r << 4;
|
||||
|
||||
return *r;
|
||||
}
|
||||
|
||||
static int
|
||||
connect_client(struct vhd_minimal_pmd_bulk *vhd)
|
||||
{
|
||||
struct lws_client_connect_info i;
|
||||
|
||||
memset(&i, 0, sizeof(i));
|
||||
|
||||
i.context = vhd->context;
|
||||
i.port = 7681;
|
||||
i.address = "localhost";
|
||||
i.path = "/";
|
||||
i.host = i.address;
|
||||
i.origin = i.address;
|
||||
i.ssl_connection = 0;
|
||||
i.vhost = vhd->vhost;
|
||||
i.protocol = "lws-minimal-pmd-bulk";
|
||||
i.pwsi = &vhd->client_wsi;
|
||||
|
||||
return !lws_client_connect_via_info(&i);
|
||||
}
|
||||
|
||||
static void
|
||||
schedule_callback(struct lws *wsi, int reason, int secs)
|
||||
{
|
||||
lws_timed_callback_vh_protocol(lws_get_vhost(wsi),
|
||||
lws_get_protocol(wsi), reason, secs);
|
||||
}
|
||||
|
||||
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 *pss =
|
||||
(struct per_session_data__minimal_pmd_bulk *)user;
|
||||
struct vhd_minimal_pmd_bulk *vhd = (struct vhd_minimal_pmd_bulk *)
|
||||
lws_protocol_vh_priv_get(lws_get_vhost(wsi),
|
||||
lws_get_protocol(wsi));
|
||||
uint8_t buf[LWS_PRE + MESSAGE_CHUNK_SIZE], *start = &buf[LWS_PRE], *p;
|
||||
int n, m, flags;
|
||||
|
||||
switch (reason) {
|
||||
|
||||
case LWS_CALLBACK_PROTOCOL_INIT:
|
||||
vhd = lws_protocol_vh_priv_zalloc(lws_get_vhost(wsi),
|
||||
lws_get_protocol(wsi),
|
||||
sizeof(struct vhd_minimal_pmd_bulk));
|
||||
if (!vhd)
|
||||
return -1;
|
||||
|
||||
vhd->context = lws_get_context(wsi);
|
||||
vhd->vhost = lws_get_vhost(wsi);
|
||||
|
||||
/* get the pointer to "interrupted" we were passed in pvo */
|
||||
vhd->interrupted = (int *)lws_pvo_search(
|
||||
(const struct lws_protocol_vhost_options *)in,
|
||||
"interrupted")->value;
|
||||
vhd->options = (int *)lws_pvo_search(
|
||||
(const struct lws_protocol_vhost_options *)in,
|
||||
"options")->value;
|
||||
|
||||
if (connect_client(vhd))
|
||||
schedule_callback(wsi, LWS_CALLBACK_USER, 1);
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_CLIENT_ESTABLISHED:
|
||||
pss->rng_tx = 4;
|
||||
pss->rng_rx = 4;
|
||||
lws_callback_on_writable(wsi);
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_CLIENT_WRITEABLE:
|
||||
|
||||
/*
|
||||
* when we connect, we will send the server a message
|
||||
*/
|
||||
|
||||
if (pss->position_tx == MESSAGE_SIZE)
|
||||
break;
|
||||
|
||||
/* fill up one chunk's worth of message content */
|
||||
|
||||
p = start;
|
||||
n = MESSAGE_CHUNK_SIZE;
|
||||
if (n > MESSAGE_SIZE - pss->position_tx)
|
||||
n = MESSAGE_SIZE - pss->position_tx;
|
||||
|
||||
flags = lws_write_ws_flags(LWS_WRITE_BINARY, !pss->position_tx,
|
||||
pss->position_tx + n == MESSAGE_SIZE);
|
||||
|
||||
/*
|
||||
* select between producing compressible repeated text,
|
||||
* or uncompressible PRNG output
|
||||
*/
|
||||
|
||||
if (*vhd->options & 1) {
|
||||
while (n) {
|
||||
size_t s;
|
||||
|
||||
m = pss->position_tx % REPEAT_STRING_LEN;
|
||||
s = REPEAT_STRING_LEN - m;
|
||||
if (s > (size_t)n)
|
||||
s = n;
|
||||
memcpy(p, &redundant_string[m], s);
|
||||
pss->position_tx += s;
|
||||
p += s;
|
||||
n -= s;
|
||||
}
|
||||
} else {
|
||||
pss->position_tx += n;
|
||||
while (n--)
|
||||
*p++ = rng(&pss->rng_tx);
|
||||
}
|
||||
|
||||
n = lws_ptr_diff(p, start);
|
||||
m = lws_write(wsi, start, n, flags);
|
||||
if (m < n) {
|
||||
lwsl_err("ERROR %d writing ws\n", m);
|
||||
return -1;
|
||||
}
|
||||
if (pss->position_tx != MESSAGE_SIZE) /* if more to do... */
|
||||
lws_callback_on_writable(wsi);
|
||||
else
|
||||
/* if we sent and received everything */
|
||||
if (pss->position_rx == MESSAGE_SIZE)
|
||||
*vhd->interrupted = 2;
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_CLIENT_RECEIVE:
|
||||
|
||||
/*
|
||||
* When we connect, the server will send us a message too
|
||||
*/
|
||||
|
||||
lwsl_user("LWS_CALLBACK_CLIENT_RECEIVE: %4d (rpp %5d, last %d)\n",
|
||||
(int)len, (int)lws_remaining_packet_payload(wsi),
|
||||
lws_is_final_fragment(wsi));
|
||||
|
||||
if (*vhd->options & 1) {
|
||||
while (len) {
|
||||
size_t s;
|
||||
|
||||
m = pss->position_rx % REPEAT_STRING_LEN;
|
||||
s = REPEAT_STRING_LEN - m;
|
||||
if (s > len)
|
||||
s = len;
|
||||
if (memcmp(in, &redundant_string[m], s)) {
|
||||
lwsl_user("echo'd data doesn't match\n");
|
||||
return -1;
|
||||
}
|
||||
pss->position_rx += s;
|
||||
in += s;
|
||||
len -= s;
|
||||
}
|
||||
} else {
|
||||
p = (uint8_t *)in;
|
||||
pss->position_rx += len;
|
||||
while (len--)
|
||||
if (*p++ != (uint8_t)rng(&pss->rng_rx)) {
|
||||
lwsl_user("echo'd data doesn't match\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we sent and received everything */
|
||||
|
||||
if (pss->position_rx == MESSAGE_SIZE &&
|
||||
pss->position_tx == MESSAGE_SIZE)
|
||||
*vhd->interrupted = 2;
|
||||
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
|
||||
lwsl_err("CLIENT_CONNECTION_ERROR: %s\n",
|
||||
in ? (char *)in : "(null)");
|
||||
vhd->client_wsi = NULL;
|
||||
schedule_callback(wsi, LWS_CALLBACK_USER, 1);
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_CLIENT_CLOSED:
|
||||
vhd->client_wsi = NULL;
|
||||
schedule_callback(wsi, LWS_CALLBACK_USER, 1);
|
||||
break;
|
||||
|
||||
/* rate-limited client connect retries */
|
||||
|
||||
case LWS_CALLBACK_USER:
|
||||
lwsl_notice("%s: LWS_CALLBACK_USER\n", __func__);
|
||||
if (connect_client(vhd))
|
||||
schedule_callback(wsi, LWS_CALLBACK_USER, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define LWS_PLUGIN_PROTOCOL_MINIMAL_PMD_BULK \
|
||||
{ \
|
||||
"lws-minimal-pmd-bulk", \
|
||||
callback_minimal_pmd_bulk, \
|
||||
sizeof(struct per_session_data__minimal_pmd_bulk), \
|
||||
4096, \
|
||||
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_PMD_BULK
|
||||
};
|
||||
|
||||
LWS_EXTERN LWS_VISIBLE int
|
||||
init_protocol_minimal_pmd_bulk(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_pmd_bulk(struct lws_context *context)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
|
@ -26,7 +26,30 @@ static struct lws_protocols protocols[] = {
|
|||
{ NULL, NULL, 0, 0 } /* terminator */
|
||||
};
|
||||
|
||||
static int interrupted;
|
||||
static int interrupted, options;
|
||||
|
||||
/* pass pointers to shared vars to the protocol */
|
||||
|
||||
static const struct lws_protocol_vhost_options pvo_options = {
|
||||
NULL,
|
||||
NULL,
|
||||
"options", /* pvo name */
|
||||
(void *)&options /* pvo value */
|
||||
};
|
||||
|
||||
static const struct lws_protocol_vhost_options pvo_interrupted = {
|
||||
&pvo_options,
|
||||
NULL,
|
||||
"interrupted", /* pvo name */
|
||||
(void *)&interrupted /* pvo value */
|
||||
};
|
||||
|
||||
static const struct lws_protocol_vhost_options pvo = {
|
||||
NULL, /* "next" pvo linked-list */
|
||||
&pvo_interrupted, /* "child" pvo linked-list */
|
||||
"lws-minimal-pmd-bulk", /* protocol name we belong to on this vhost */
|
||||
"" /* ignored */
|
||||
};
|
||||
|
||||
static const struct lws_http_mount mount = {
|
||||
/* .mount_next */ NULL, /* linked-list "next" */
|
||||
|
@ -64,6 +87,16 @@ void sigint_handler(int sig)
|
|||
interrupted = 1;
|
||||
}
|
||||
|
||||
static int findswitch(int argc, char **argv, const char *val)
|
||||
{
|
||||
while (--argc > 0) {
|
||||
if (!strcmp(argv[argc], val))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct lws_context_creation_info info;
|
||||
|
@ -76,7 +109,14 @@ int main(int argc, char **argv)
|
|||
info.port = 7681;
|
||||
info.mounts = &mount;
|
||||
info.protocols = protocols;
|
||||
info.extensions = extensions;
|
||||
info.pvo = &pvo;
|
||||
|
||||
if (!findswitch(argc, argv, "-n"))
|
||||
info.extensions = extensions;
|
||||
|
||||
if (!findswitch(argc, argv, "-c"))
|
||||
options |= 1;
|
||||
|
||||
info.pt_serv_buf_size = 32 * 1024;
|
||||
|
||||
lws_set_log_level(LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE
|
||||
|
@ -88,7 +128,7 @@ int main(int argc, char **argv)
|
|||
/* | LLL_DEBUG */, NULL);
|
||||
|
||||
lwsl_user("LWS minimal ws server + permessage-deflate | visit http://localhost:7681\n");
|
||||
|
||||
lwsl_user(" %s [-n (no exts)] [-c (compressible)]\n", argv[0]);
|
||||
context = lws_create_context(&info);
|
||||
if (!context) {
|
||||
lwsl_err("lws init failed\n");
|
||||
|
|
|
@ -61,9 +61,12 @@ try {
|
|||
ws.onmessage =function got_packet(msg) {
|
||||
console.log("Received ws message len " + msg.data.length);
|
||||
document.getElementById("r").value =
|
||||
document.getElementById("r").value + msg.data + "\n";
|
||||
document.getElementById("r").value + "\nReceived: " + msg.data.length + " bytes\n";
|
||||
document.getElementById("r").scrollTop =
|
||||
document.getElementById("r").scrollHeight;
|
||||
|
||||
/* echo it back */
|
||||
ws.send(msg.data);
|
||||
}
|
||||
|
||||
ws.onclose = function(){
|
||||
|
|
|
@ -56,64 +56,96 @@ static const char * const redundant_string =
|
|||
/* one of these is created for each client connecting to us */
|
||||
|
||||
struct per_session_data__minimal_pmd_bulk {
|
||||
int position; /* byte position we got up to sending the message */
|
||||
uint64_t rng;
|
||||
int position_tx, position_rx;
|
||||
uint64_t rng_rx, rng_tx;
|
||||
};
|
||||
|
||||
struct vhd_minimal_pmd_bulk {
|
||||
int *interrupted;
|
||||
int *options; /* b0 = 1: test compressible text, = 0: test uncompressible binary */
|
||||
};
|
||||
|
||||
static uint64_t rng(uint64_t *r)
|
||||
{
|
||||
*r ^= *r << 21;
|
||||
*r ^= *r >> 35;
|
||||
*r ^= *r << 4;
|
||||
|
||||
return *r;
|
||||
}
|
||||
|
||||
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 *pss =
|
||||
(struct per_session_data__minimal_pmd_bulk *)user;
|
||||
struct vhd_minimal_pmd_bulk *vhd = (struct vhd_minimal_pmd_bulk *)
|
||||
lws_protocol_vh_priv_get(lws_get_vhost(wsi),
|
||||
lws_get_protocol(wsi));
|
||||
uint8_t buf[LWS_PRE + MESSAGE_CHUNK_SIZE], *start = &buf[LWS_PRE], *p;
|
||||
int n, m, flags;
|
||||
int n, m, flags, olen;
|
||||
|
||||
switch (reason) {
|
||||
case LWS_CALLBACK_PROTOCOL_INIT:
|
||||
vhd = lws_protocol_vh_priv_zalloc(lws_get_vhost(wsi),
|
||||
lws_get_protocol(wsi),
|
||||
sizeof(struct vhd_minimal_pmd_bulk));
|
||||
if (!vhd)
|
||||
return -1;
|
||||
|
||||
/* get the pointer to "interrupted" we were passed in pvo */
|
||||
vhd->interrupted = (int *)lws_pvo_search(
|
||||
(const struct lws_protocol_vhost_options *)in,
|
||||
"interrupted")->value;
|
||||
vhd->options = (int *)lws_pvo_search(
|
||||
(const struct lws_protocol_vhost_options *)in,
|
||||
"options")->value;
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_ESTABLISHED:
|
||||
pss->position = 0;
|
||||
pss->rng = 4;
|
||||
pss->rng_tx = 4;
|
||||
pss->rng_rx = 4;
|
||||
lws_callback_on_writable(wsi);
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_SERVER_WRITEABLE:
|
||||
if (pss->position == MESSAGE_SIZE)
|
||||
if (pss->position_tx == MESSAGE_SIZE)
|
||||
break;
|
||||
|
||||
/* fill up one chunk's worth of message content */
|
||||
|
||||
p = start;
|
||||
n = MESSAGE_CHUNK_SIZE;
|
||||
if (n > MESSAGE_SIZE - pss->position)
|
||||
n = MESSAGE_SIZE - pss->position;
|
||||
if (n > MESSAGE_SIZE - pss->position_tx)
|
||||
n = MESSAGE_SIZE - pss->position_tx;
|
||||
|
||||
flags = lws_write_ws_flags(LWS_WRITE_TEXT, !pss->position,
|
||||
pss->position + n == MESSAGE_SIZE);
|
||||
flags = lws_write_ws_flags(LWS_WRITE_BINARY, !pss->position_tx,
|
||||
pss->position_tx + n == MESSAGE_SIZE);
|
||||
|
||||
/*
|
||||
* select between producing compressible repeated text,
|
||||
* or uncompressible PRNG output
|
||||
*/
|
||||
#if 0
|
||||
while (n) {
|
||||
m = pss->position % REPEAT_STRING_LEN;
|
||||
s = REPEAT_STRING_LEN - m;
|
||||
if (s > n)
|
||||
s = n;
|
||||
memcpy(p, &redundant_string[m], s);
|
||||
pss->position += s;
|
||||
p += s;
|
||||
n -= s;
|
||||
|
||||
if (*vhd->options & 1) {
|
||||
while (n) {
|
||||
size_t s;
|
||||
|
||||
m = pss->position_tx % REPEAT_STRING_LEN;
|
||||
s = REPEAT_STRING_LEN - m;
|
||||
if (s > (size_t)n)
|
||||
s = n;
|
||||
memcpy(p, &redundant_string[m], s);
|
||||
pss->position_tx += s;
|
||||
p += s;
|
||||
n -= s;
|
||||
}
|
||||
} else {
|
||||
pss->position_tx += n;
|
||||
while (n--)
|
||||
*p++ = rng(&pss->rng_tx);
|
||||
}
|
||||
#else
|
||||
pss->position += n;
|
||||
while (n--) {
|
||||
pss->rng ^= pss->rng << 21;
|
||||
pss->rng ^= pss->rng >> 35;
|
||||
pss->rng ^= pss->rng << 4;
|
||||
*p++ = 0x40 + ((pss->rng >> (n & 15)) & 0x3f);
|
||||
}
|
||||
#endif
|
||||
|
||||
n = lws_ptr_diff(p, start);
|
||||
m = lws_write(wsi, start, n, flags);
|
||||
|
@ -121,10 +153,48 @@ callback_minimal_pmd_bulk(struct lws *wsi, enum lws_callback_reasons reason,
|
|||
lwsl_err("ERROR %d writing ws\n", n);
|
||||
return -1;
|
||||
}
|
||||
if (pss->position != MESSAGE_SIZE) /* if more to do... */
|
||||
if (pss->position_tx != MESSAGE_SIZE) /* if more to do... */
|
||||
lws_callback_on_writable(wsi);
|
||||
break;
|
||||
|
||||
case LWS_CALLBACK_RECEIVE:
|
||||
lwsl_user("LWS_CALLBACK_RECEIVE: %4d (pss->pos=%d, rpp %5d, last %d)\n",
|
||||
(int)len, (int)pss->position_rx, (int)lws_remaining_packet_payload(wsi),
|
||||
lws_is_final_fragment(wsi));
|
||||
olen = len;
|
||||
|
||||
if (*vhd->options & 1) {
|
||||
while (len) {
|
||||
size_t s;
|
||||
m = pss->position_rx % REPEAT_STRING_LEN;
|
||||
s = REPEAT_STRING_LEN - m;
|
||||
if (s > len)
|
||||
s = len;
|
||||
if (memcmp(in, &redundant_string[m], s)) {
|
||||
lwsl_user("echo'd data doesn't match\n");
|
||||
return -1;
|
||||
}
|
||||
pss->position_rx += s;
|
||||
in += s;
|
||||
len -= s;
|
||||
}
|
||||
} else {
|
||||
p = (uint8_t *)in;
|
||||
pss->position_rx += len;
|
||||
while (len--) {
|
||||
if (*p++ != (uint8_t)rng(&pss->rng_rx)) {
|
||||
lwsl_user("echo'd data doesn't match: 0x%02X 0x%02X (%d)\n",
|
||||
*(p - 1), (int)(0x40 + (pss->rng_rx & 0x3f)),
|
||||
(int)((pss->position_rx - olen) + olen - len));
|
||||
lwsl_hexdump_notice(in, olen);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (pss->position_rx == MESSAGE_SIZE)
|
||||
pss->position_rx = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue