diff --git a/README-test-server b/README-test-server index 89ade554..bc9d65cb 100644 --- a/README-test-server +++ b/README-test-server @@ -36,7 +36,11 @@ $ libwebsockets-test-server should be enough to get a test server listening on port 7861. -There are a couple of other possible configure options + +Configure script options +------------------------ + +There are several other possible configure options --enable-nofork disables the fork into the background API and removes all references to fork() and @@ -103,7 +107,11 @@ tradeoff between taking too much and needless realloc the header value string keeps coming - MAX_USER_RX_BUFFER default 4096: max amount of user rx data to buffer at a -time and pass to user callback +time and pass to user callback LWS_CALLBACK_RECEIVE or +LWS_CALLBACK_CLIENT_RECEIVE. Large frames are passed to the user callback +in chunks of this size. Tradeoff between per-connection static memory +allocation and if you expect to deal with large frames, how much you can +see at once which can affect efficiency. - MAX_BROADCAST_PAYLOAD default 4096: largest amount of user tx data we can broadcast at a time @@ -120,7 +128,14 @@ for later protocol versions... unlikely - AWAITING_TIMEOUT default 5: after this many seconds without a response, the server will hang up on the client - - CIPHERS_LIST_STRING default "DEFAULT": SSL Cipher selection + - CIPHERS_LIST_STRING default "DEFAULT": SSL Cipher selection. It's advisable +to tweak the ciphers allowed to be negotiated on secure connections for +performance reasons, otherwise a slow algorithm may be selected by the two +endpoints and the server could expend most of its time just encrypting and +decrypting data, severely limiting the amount of messages it will be able to +handle per second. For example:: + + "RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL" - SYSTEM_RANDOM_FILEPATH default "/dev/urandom": if your random device differs you can set it here @@ -171,6 +186,37 @@ configure option --nofork and simply call libwebsocket_service() from your own main loop as shown in the test app sources. +Fragmented messages +------------------- + +To support fragmented messages you need to check for the final +frame of a message with libwebsocket_is_final_fragment. This +check can be combined with libwebsockets_remaining_packet_payload +to gather the whole contents of a message, eg: + + case LWS_CALLBACK_RECEIVE: + { + Client * const client = (Client *)user; + const size_t remaining = libwebsockets_remaining_packet_payload(wsi); + + if (!remaining && libwebsocket_is_final_fragment(wsi)) { + if (client->HasFragments()) { + client->AppendMessageFragment(in, len, 0); + in = (void *)client->GetMessage(); + len = client->GetMessageLength(); + } + + client->ProcessMessage((char *)in, len, wsi); + client->ResetMessage(); + } else + client->AppendMessageFragment(in, len, remaining); + } + break; + +The test app llibwebsockets-test-fraggle sources also show how to +deal with fragmented messages. + + Testing websocket client support -------------------------------- diff --git a/README.rst b/README.rst deleted file mode 100644 index f9989aa2..00000000 --- a/README.rst +++ /dev/null @@ -1,72 +0,0 @@ - -Useful tips for using `libwebsockets` -===================================== - -Maximum number of clients -------------------------- -There is a hard limit on the maximum number of clients the library will accept and by default it is set to **100**. -This limit can be changed by modifying the **MAX_CLIENTS** preprocessor macro in the file -**lib/private-libwebsockets.h**. The higher the limit the more memory the library will allocate at startup. - -SSL performance ---------------- -It is recommended to tweak the ciphers allowed on secure connections for performance reasons, -otherwise a slow algorithm may be selected by the two endpoints and the server could expend most of its time just -encrypting and decrypting data, severely limiting the amount of messages it will be able to handle per second. -To limit the ciphers supported on secure connections you should modify the preprocessor macro **CIPHERS_LIST_STRING** -in the file **lib/private-libwebsockets.h**. For example:: - - #define CIPHERS_LIST_STRING "RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL" - -Other tweaks ------------- -There are several preprocessor macros that could be tweaked to reduce memory usage, -to increase performance or to change the behaviour of the library to suit your needs, -they are all located in the file **lib/private-libwebsockets.h**. - -Big frames ----------- -The library process data from the sockets in chunks of **4KB** (defined by the macro **MAX_USER_RX_BUFFER**), -these chunks will be passed to the client callback as **LWS_CALLBACK_RECEIVE**. -If you want to know whether you have all the data for the current frame you need to use the function -**libwebsockets_remaining_packet_payload**. - -Fragmented messages -------------------- -To support fragmented messages you need to check for the final frame of a message with -**libwebsocket_is_final_fragment**. This check can be combined with **libwebsockets_remaining_packet_payload** -to gather the whole contents of a message like in this example:: - - case LWS_CALLBACK_RECEIVE: - { - Client * const client = (Client *)user; - const size_t remaining = libwebsockets_remaining_packet_payload(wsi); - if (0 == remaining && - libwebsocket_is_final_fragment(wsi)) - { - if (client->HasFragments()) - { - client->AppendMessageFragment(in, len, 0); - in = (void *)client->GetMessage(); - len = client->GetMessageLength(); - } - - client->ProcessMessage((char *)in, len, wsi); - - client->ResetMessage(); - } - else - { - client->AppendMessageFragment(in, len, remaining); - } - } - break; - -HTTP requests -------------- -If your server is going to support regular HTTP requests by handling **LWS_CALLBACK_HTTP** it is recommended to -**return 1** as the result of the callback after you write the response, -this will tell the library to automatically close the connection. -Closing the connection will liberate an slot for another HTTP request, -otherwise it would be up to the browser to close the connection, -which could be an issue because the library has a hard limit on the number of open connections, as explained before. diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h index ef951d62..0c7c2eca 100644 --- a/lib/libwebsockets.h +++ b/lib/libwebsockets.h @@ -369,6 +369,14 @@ struct libwebsocket_extension; * @in points to the URI path requested and * libwebsockets_serve_http_file() makes it very * simple to send back a file to the client. + * Normally after sending the file you are done + * with the http connection, since the rest of the + * activity will come by websockets from the script + * that was delivered by http, so you will want to + * return 1; to close and free up the connection. + * That's important because it uses a slot in the + * total number of client connections allowed set + * by MAX_CLIENTS. * * LWS_CALLBACK_CLIENT_WRITEABLE: * LWS_CALLBACK_SERVER_WRITEABLE: If you call diff --git a/libwebsockets-api-doc.html b/libwebsockets-api-doc.html index acda2b57..00d38e1c 100644 --- a/libwebsockets-api-doc.html +++ b/libwebsockets-api-doc.html @@ -629,6 +629,14 @@ which will then open the websockets connection. in points to the URI path requested and libwebsockets_serve_http_file makes it very simple to send back a file to the client. +Normally after sending the file you are done +with the http connection, since the rest of the +activity will come by websockets from the script +that was delivered by http, so you will want to +return 1; to close and free up the connection. +That's important because it uses a slot in the +total number of client connections allowed set +by MAX_CLIENTS.

LWS_CALLBACK_SERVER_WRITEABLE

diff --git a/test-server/test-server-extpoll.c b/test-server/test-server-extpoll.c index 6266e9fb..3289ba76 100644 --- a/test-server/test-server-extpoll.c +++ b/test-server/test-server-extpoll.c @@ -105,7 +105,8 @@ static int callback_http(struct libwebsocket_context * this, if (libwebsockets_serve_http_file(wsi, LOCAL_RESOURCE_PATH"/test.html", "text/html")) fprintf(stderr, "Failed to send HTTP file\n"); - break; + /* we are done with this connnection */ + return 1; /* * callback for confirming to continue with client IP appear in diff --git a/test-server/test-server.c b/test-server/test-server.c index 06bfd6e2..f66ea421 100644 --- a/test-server/test-server.c +++ b/test-server/test-server.c @@ -85,7 +85,9 @@ static int callback_http(struct libwebsocket_context *context, if (libwebsockets_serve_http_file(wsi, LOCAL_RESOURCE_PATH"/test.html", "text/html")) fprintf(stderr, "Failed to send HTTP file\n"); - break; + + /* we are done with this http connection */ + return 1; /* * callback for confirming to continue with client IP appear in