[Libwebsockets] Send data with libwebsockets

Andy Green andy at warmcat.com
Tue Oct 28 00:27:15 CET 2014



On 28 October 2014 05:08:52 GMT+08:00, Stefano Sabatini <stefasab at gmail.com> wrote:
>Hi,
>
>I'm a newbie with libwebsockets and I think I'm doing something wrong
>with it.

Yeah there are a couple of problems with your code.

>I have this code in my protocol callback:
> 
>    case LWS_CALLBACK_RECEIVE:
>        printf("Received data: %s\n", (char *)in);
>        /* send JPEG compressed image */
>        {
>#define PAYLOAD_SIZE 4096
>char buf[LWS_SEND_BUFFER_PRE_PADDING + PAYLOAD_SIZE +
>LWS_SEND_BUFFER_POST_PADDING];

This is good.

>            int n;
>            // read data from file
>            const char *filename = "lena.jpeg";
>            FILE *f = fopen(filename, "r");
>            if (!f) {
>               fprintf(stderr, "Could not open file '%s'\n", filename);
>                break;
>            }
>
>            printf("Sending image data...\n");
>while (n = fread(buf + LWS_SEND_BUFFER_PRE_PADDING, 1, PAYLOAD_SIZE,
>f)) {

You can't loop like this.

lws should never do anything that will block.

If lena.jpg is big enough and depending on network conditions to the peer, this will always block.  Other connections or input on this connection will not get processed while it blocks.

>                printf("Sending %d bytes...\n", n);
>       // memset(&buf[LWS_SEND_BUFFER_PRE_PADDING], 255, PAYLOAD_SIZE);
>libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], n,
>LWS_WRITE_TEXT);

Eventually writing more on the socket won't be accepted by the kernel.

What you should be doing is only writing on the connection in the LWS_CALLBACK_SERVER_WRITEABLE callback, and if you have something you want to write, arrange to get a WRITEABLE callback using libwebsocket_callback_on_writable(context, wsi); and send one fragment of your message each time.

This way even extremely laggy or low bandwidth connections will regulate themselves without blocking and you can handle many (tens of thousands) of simultaneous connections cleanly.

And this is sending one logical websocket message per 4K or whatever.  It's probably not what you want.  Have a look in test-fraggle.c to see how to use LWS_WRITE_NO_FIN.

>            }
>            fclose(f);
>        }
>        break;
>
>
>This causes a failure on the client side, which closes the connection.

I can't say why but probably because it's getting several ws messages each with a piece of jpeg in them.

>Question is: if we have to send data using several segments, what's
>the supposed way to do it? Or should I assemble the complete data and
>send it with a single call to libwebsocket_write()?

No see above about fraggle.

>Also sometimes I'm getting this on the server side:
>Sending image data...
>Sending 4096 bytes...
>Sending 4096 bytes...
>Sending 4096 bytes...
>lwsts[13497]: ****** 7e53e0 Sending new, pending truncated ...
>hellowebsockets: /home/stefano/src/libwebsockets/lib/output.c:112:
>lws_issue_raw: Assertion `0' failed.
>
>Is this a bug, should I fill a bug report for that?

Please use current lws from git.

-Andy

>Thanks in advance.
>_______________________________________________
>Libwebsockets mailing list
>Libwebsockets at ml.libwebsockets.org
>http://ml.libwebsockets.org/mailman/listinfo/libwebsockets




More information about the Libwebsockets mailing list