[Libwebsockets] Problem with more than 1 client

Stefano Mora stefano.mora at newdep.com
Tue Apr 23 11:42:54 CEST 2019


Hi all,
I'm writing a ws server based on the lws_minimal sample (with ring).
So far I had no special problem but I was working with only one client.
Now I need to turn on to a two clients and the problems started: I'll try to describe them.

In my project I have two kind of replies:

  1.  The server must reply to a command sent by a specific client: the reply is only addressed to that client
  2.  Some commands are generated by the internal lws timer: the server will send the reply to every connected client (as notify)

I wrote a function that handles this looking for wsi parameter (if null then send to every connected client):

void wsSendMessageToRing(char* pMsg, int len, struct lws *wsi)
{
                struct msg amsg;

                struct per_vhost_data *vhd =
                               (struct per_vhost_data *)
                               (wsi ? lws_protocol_vh_priv_get( lws_get_vhost(wsi), lws_get_protocol(wsi)) : engineData.vhd);
                int n = (int)lws_ring_get_count_free_elements(vhd->ring);
                if (!n) {
                               /* forcibly make space */
                               cull_lagging_clients(vhd);
                               n = (int)lws_ring_get_count_free_elements(vhd->ring);
                }
                if (!n){
                               lwsl_err("ring full!\n");
                               return;
                }

                amsg.len = len;
                /* notice we over-allocate by LWS_PRE... */
                amsg.payload = malloc(LWS_PRE + len);
                if (!amsg.payload) {
                               lwsl_user("OOM: dropping\n");
                               return;
                }

                /* ...and we copy the payload in at +LWS_PRE */
                memcpy((char *)amsg.payload + LWS_PRE, pMsg, len);
                if (!lws_ring_insert(vhd->ring, &amsg, 1)) {
                               __destroy_message(&amsg);
                               lwsl_user("dropping!\n");
                               return;
                };

                if (wsi){
                               lwsl_user("!! on_writable ToRing1 vhd=%p wdi=%p msg='%s'\n", vhd, wsi, pMsg);
                               lws_callback_on_writable(wsi);
                }
                else {
                               /*
                               * let everybody know we want to write something on them
                               * as soon as they are ready
                               */
                               lws_start_foreach_llp(struct per_session_data **, ppss, vhd->pss_list) {
                                               lwsl_user("!! on_writable ToRingM vhd=%p pss=%p wdi=%p msg='%s'\n",
                                                               vhd, (*ppss), (*ppss)->wsi, pMsg);
                                               lws_callback_on_writable((*ppss)->wsi);
                               } lws_end_foreach_llp(ppss, pss_list);
                }
}

This is the log I get on the server (lines starting with '##' are my remarks) :

## server starts

[2019/04/19 18:24:15:8540] [ws-server.c][main] - Apr 19 2019 14:36:11
[2019/04/19 18:24:15:8540] [ws-server.c][main] - START
Lib Version: 3.1.99 v3.1.0-37-g10bf337b
[2019/04/19 18:24:15:8540] [ws-server.c][main] - engineData.context 0x7fd48f68
[2019/04/19 18:24:15:8549] [protocol_lws.c][wsCallback] LWS_CALLBACK_PROTOCOL_INIT
Version MULTICLIENT
[2019/04/19 18:24:15:8550] [protocolCPTouch.c][SetEngineDefaultValues] Setting Engine default values

## first client arrives ..

[2019/04/19 18:24:15:8813] [protocol_lws.c][wsCallback] LWS_CALLBACK_ESTABLISHED [run:0][nCli:0]
[2019/04/19 18:24:15:8813] [protocol_lws.c] pss=0x7fd49c90 wsi=0x7fd49768

## .. and sends some commands:

LWS_RECEIVE len=24
LWS_RECEIVE pss=0x7fd49c90 in='{"setPort":"/dev/ttyS1"}'
[2019/04/19 18:24:15:8844] [io.c][io] cmd: {"setPort":"/dev/ttyS1"}
!! on_writable ToRing1 vhd=0x7fd496d8 wdi=0x7fd49768 msg='initSetPort'
[2019/04/19 18:24:15:8846] [protocol_lws.c][writable] vhd=0x7fd496d8 pss=0x7fd49c90 'initSetPort' tail=2144640152
WRITABLE end

LWS_RECEIVE len=16
LWS_RECEIVE pss=0x7fd49c90 in='{"setMode":"CP"}'
[2019/04/19 18:24:15:8880] [io.c][io] cmd: {"setMode":"CP"}
!! on_writable ToRing1 vhd=0x7fd496d8 wdi=0x7fd49768 msg='initSetMode'
[2019/04/19 18:24:15:8882] [protocol_lws.c][writable] vhd=0x7fd496d8 pss=0x7fd49c90 'initSetMode' tail=2144640152
WRITABLE end

LWS_RECEIVE len=10
LWS_RECEIVE pss=0x7fd49c90 in='startKiosk'
[2019/04/19 18:24:15:9371] [io.c][io] cmd: startKiosk
ClientMode: CP
Numero clients: 1
Open '/dev/ttyS1' [fd:0]
.. start timer 0x7fd49768 ..
.. End startKiosk

!! on_writable ToRing1 vhd=0x7fd496d8 wdi=0x7fd49768 msg='EndStartKiosk'
[2019/04/19 18:24:17:3434] [protocol_lws.c][writable] vhd=0x7fd496d8 pss=0x7fd49c90 'EndStartKiosk' tail=2144640152
WRITABLE end

## internal timer starts to send notification to the client (note 'ToRingM' vs previous 'ToRing1'):

!! on_writable ToRingM vhd=0x7fd496d8 pss=0x7fd49c90 wdi=0x7fd49768 msg='{ "cmd":"firmware", "v":"1.3"}'
[2019/04/19 18:24:19:6900] [protocol_lws.c][writable] vhd=0x7fd496d8 pss=0x7fd49c90 '{ "cmd":"firmware", "v":"1.3"}' tail=2144640152
WRITABLE end

!! on_writable ToRingM vhd=0x7fd496d8 pss=0x7fd49c90 wdi=0x7fd49768 msg='{ "cmd":"firmware", "v":"1.3"}'
[2019/04/19 18:24:29:1926] [protocol_lws.c][writable] vhd=0x7fd496d8 pss=0x7fd49c90 '{ "cmd":"firmware", "v":"1.3"}' tail=2144640152
WRITABLE end

## .. time passes ..
## second client arrives ..

[2019/04/19 18:24:51:9344] [protocol_lws.c][wsCallback] LWS_CALLBACK_ESTABLISHED [run:1][nCli:1]
[2019/04/19 18:24:51:9344] [protocol_lws.c] pss=0x7fd49d60 wsi=0x7fd49e20

## .. and sends its commands:

LWS_RECEIVE len=24
LWS_RECEIVE pss=0x7fd49d60 in='{"setPort":"/dev/ttyS1"}'
[2019/04/19 18:24:52:0051] [io.c][io] cmd: {"setPort":"/dev/ttyS1"}
!! on_writable ToRing1 vhd=0x7fd496d8 wdi=0x7fd49e20 msg='initSetPort'
[2019/04/19 18:24:52:0053] [protocol_lws.c][writable] vhd=0x7fd496d8 pss=0x7fd49d60 'initSetPort' tail=2144640360
WRITABLE end

LWS_RECEIVE len=17
LWS_RECEIVE pss=0x7fd49d60 in='{"setMode":"ADM"}'
[2019/04/19 18:24:52:0082] [io.c][io] cmd: {"setMode":"ADM"}
!! on_writable ToRing1 vhd=0x7fd496d8 wdi=0x7fd49e20 msg='initSetMode'
[2019/04/19 18:24:52:0083] [protocol_lws.c][writable] vhd=0x7fd496d8 pss=0x7fd49d60 'initSetMode' tail=2144640360
WRITABLE end

LWS_RECEIVE len=10
LWS_RECEIVE pss=0x7fd49d60 in='startKiosk'
[2019/04/19 18:24:52:0406] [io.c][io] cmd: startKiosk
ClientMode: ADM
Numero clients: 2
-> Port yet open
.. End startKiosk

!! on_writable ToRing1 vhd=0x7fd496d8 wdi=0x7fd49e20 msg='EndStartKiosk'
[2019/04/19 18:24:52:0409] [protocol_lws.c][writable] vhd=0x7fd496d8 pss=0x7fd49d60 'EndStartKiosk' tail=2144640360
WRITABLE end

## everything ok, so far ..
## now the notification timer finds two client and then push two replies on the ring ..

!! on_writable ToRingM vhd=0x7fd496d8 pss=0x7fd49d60 wdi=0x7fd49e20 msg='{ "cmd":"firmware", "v":"1.3"}'
!! on_writable ToRingM vhd=0x7fd496d8 pss=0x7fd49c90 wdi=0x7fd49768 msg='{ "cmd":"firmware", "v":"1.3"}'

## but when 'WRITABLE' phase arrives, it has a wrong reply ('initSetPort' instead of 'firmware') for the second client (??):

[2019/04/19 18:24:57:6969] [protocol_lws.c][writable] vhd=0x7fd496d8 pss=0x7fd49c90 'initSetPort' tail=2144640152
!! on_writable WRITABLE pss=0x7fd49c90 wdi=0x7fd49768 tail=2144640152
WRITABLE end

## after a while the WRITABLE phase is still alive with a correct reply ('firmware') for the first client:

[2019/04/19 18:24:57:6974] [protocol_lws.c][writable] vhd=0x7fd496d8 pss=0x7fd49d60 '{ "cmd":"firmware", "v":"1.3"}' tail=2144640360
WRITABLE end

## from now on the communication is out of phase ..

[2019/04/19 18:24:57:6976] [protocol_lws.c][writable] vhd=0x7fd496d8 pss=0x7fd49c90 'initSetMode' tail=2144640152
!! on_writable WRITABLE pss=0x7fd49c90 wdi=0x7fd49768 tail=2144640152
WRITABLE end


My guess is that I'm not handling well the messages on the ring for the clients but I'm not able to solve it.
Sorry for the long text.

Thanks, regards
---
Stefano Mora / SW Engineer
stefano.mora at newdep.com<mailto:stefano.mora at newdep.com>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://libwebsockets.org/pipermail/libwebsockets/attachments/20190423/9bdccb65/attachment-0001.htm>


More information about the Libwebsockets mailing list