[Libwebsockets] What is the proper way to send back websouckets response NOT to all connected clients

Meir Yanovich meiry242 at gmail.com
Wed May 25 13:33:18 CEST 2016

Thanks for your thought provoking answer .
so i understand that it better to response to client when he is ready to
consomme the response data.  therefore i should use
the lws_callback_on_writable(lws_get_context(wsi), wsi); function
but where ?
so the response in the LWS_CALLBACK_SERVER_WRITEABLE is wrong ?

On Wed, May 25, 2016 at 2:21 PM, Andy Green <andy at warmcat.com> wrote:

> On 05/25/2016 06:54 PM, Meir Yanovich wrote:
>> Hello all
>> i want to be able to send back response only to selected connected
>> clients and not as
>> shown in the example using :
>> lws_callback_on_writable_all_protocol.
>> i searched the mailing list and found this answer :
>> https://libwebsockets.org/pipermail/libwebsockets/2016-January/002177.html
>> As suggested i need to keep list of wsi amd user id's
>> I just didn't understand why i need to use lws_callback_on_writable()
> This is a "nonblocking vs blocking" network programming question rather
> than a lws one.
> Imagine you have three clients connected, that you want to send stuff to.
>  - one is localhost.  He can eat the data as fast as you send it.
>  - the second is in another continent.  He is restricted how quickly he
> can eat data.
>  - the third is on the London Underground with a 3G phone.  (As opposed to
> the Taiwanese MRT, which has global coverage for phones even underground,
> because it got started a bit later than 1906).
> The only way to unify these guys is to modulate what is sent by when they
> individually ACK what was sent before.  Otherwise who will hold the
> increasing pile of data for the 3G phone when he is incommunicado in a
> tunnel?
> As you can see i will invoke function to response to selected users
>> Now what i have in my web socket handler/callback function :
>> where do i need to use lws_callback_on_writable() ?
> Fundamentally because different clients eat your data at different rates,
> and sometimes their connectivity goes away for a while.
> You cannot just spam data at each client because it became ready. Threaded
> / blocking programming makes it look like that while someone is eating the
> data quickly, but actually even there some connections will block forever
> and you don't have infinite storage, so you have the same problem.  One way
> or the other, you must hold the data until the client can eat it, or you
> decide you don't want to burn memory holding it any more and it will never
> get that data.
> If you have to feed two babies, and one eats slower than the other, the
> point is not that you have the food on the plate it's that the individual
> baby is ready and willing for another spoonful; that will decide the rate
> any progress is made and it's different for each baby.
> That's why we talk about "when writable" as the primitive for the
> individual connections rather than "when you have data to send".
> -Andy
> switch (reason) { case LWS_CALLBACK_ESTABLISHED:
>> pss->recive_all_from_client = 0; break; case
>> LWS_CALLBACK_SERVER_WRITEABLE: if (pss->recive_all_from_client == 1) {
>> root = cJSON_CreateObject(); cJSON_AddItemToObject(root, "text",
>> cJSON_CreateString(pss->text_string)); cJSON_AddItemToObject(root, "id",
>> cJSON_CreateString(pss->id_string)); cJSON_AddItemToObject(root, "msg",
>> cJSON_CreateString("Thanks!")); resp_json = cJSON_Print(root); n =
>> sprintf((char *)pout, "%s", resp_json); //m = lws_write(wsi, out,
>> sizeof(out), LWS_WRITE_TEXT); if (m < n) { lwsl_err("ERROR %d writing to
>> di socket\n", sizeof(out)); return -1; } /* // Here i will keep the wsi
>> and the user id in some vector or list */ //Invoke response to selected
>> users ... } break; case LWS_CALLBACK_RECEIVE: if (len < 1) { break; }
>> lwsl_notice("Request from server: %s \n", (const char *)in); cJSON *
>> user_root = cJSON_Parse((const char *)in); cJSON * user_type =
>> cJSON_GetObjectItem(user_root, "type"); cJSON * user_text =
>> cJSON_GetObjectItem(user_root, "text"); cJSON * user_id =
>> cJSON_GetObjectItem(user_root, "id"); cJSON * user_date =
>> cJSON_GetObjectItem(user_root, "date"); strcpy(pss->type_string,
>> user_type->valuestring); strcpy(pss->text_string,
>> user_text->valuestring); strcpy(pss->id_string, user_id->valuestring);
>> strcpy(pss->date_string, user_date->valuestring);
>> pss->recive_all_from_client = 1; break; case
>> _______________________________________________
>> Libwebsockets mailing list
>> Libwebsockets at ml.libwebsockets.org
>> http://libwebsockets.org/mailman/listinfo/libwebsockets
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://libwebsockets.org/pipermail/libwebsockets/attachments/20160525/4187f78b/attachment-0001.html>

More information about the Libwebsockets mailing list