2

I'm addressing an issue with WebSocket that I'm not able to understand.
Please, use the code below as reference:

int write_buffer_size = 8000 +
                LWS_SEND_BUFFER_PRE_PADDING +
                LWS_SEND_BUFFER_POST_PADDING;

char *write_buffer = new unsigned char[write_buffer_size];

/* ... other code
   write_buffer is filled in some way that is not important for the question
*/

n = libwebsocket_write(wsi, &write_buffer[LWS_SEND_BUFFER_PRE_PADDING], write_len,
            (libwebsocket_write_protocol)write_mode);
    if (n < 0) {
        cerr << "ERROR " << n << " writing to socket, hanging up" << endl;
        if (utils) {
            log = "wsmanager::error: hanging up writing to websocket";
            utils->writeLog(log);
        }
        return -1;
    }
    if (n < write_len) {
        cerr << "Partial write: " << n << " < " << write_len << endl;
        if (utils) {
            log = "wsmanager-error: websocket partial write";
            utils->writeLog(log);
        }
        return -1;
    }

When I try to send data bigger than 7160 bytes I receive always the same error, e.g. Partial write: 7160 < 8000.
Do you have any kind of explanation for that behavior?
I have allocated a buffer with 8000 bytes reserved for the payload so I was expecting to be able to send a maximum amount of data of 8K, but 7160 (bytes) seems to be the maximum amount of data I can send.
Any help is appreciated, thanks!

neoben
  • 743
  • 12
  • 30
  • See http://ml.libwebsockets.org/pipermail/libwebsockets/2013-September/000572.html – John Zwinck Dec 01 '15 at 15:28
  • Thanks, but it seems to be a different problem related to the rx buffer. In my case the issue appears writing (and not reading) to websocket. – neoben Dec 01 '15 at 15:33

2 Answers2

0

I have encountered similar problem with an older version of libwebsockets. Although I didn't monitor the limit, it was pretty much the same thing: n < write_len. I think my limit was way lower, below 2048B, and I knew that the same code worked fine with newer version of libwebsockets (on different machine).

Since Debian Jessie doesn't have lws v1.6 in repositories, I've built it from github sources. Consider upgrading, it may help solve your problem. Beware, they have changed api. It was mostly renaming of methods' names from libwebsocket_* to lws_*, but also some arguments changed. Check this pull request which migrates boilerplate libwebsockets server to version 1.6. Most of these changes will affect your code.

kecer
  • 3,031
  • 2
  • 21
  • 24
0

We solved the issue updating libwebsockets to 1.7.3 version.
We also optimized the code using a custom callback called when the channel is writable

void
WSManager::onWritable() {
    int ret, n;
    struct fragment *frg;

    pthread_mutex_lock(&send_queue_mutex);

    if (!send_queue.empty() && !lws_partial_buffered(wsi)) {
        frg = send_queue.front();

        n = lws_write(wsi, frg->content + LWS_PRE, frg->len, (lws_write_protocol)frg->mode);
        ret = checkWsWrite(n, frg->len);

        if (ret >= 0 && !lws_partial_buffered(wsi)) {
            if (frg->mode == WS_SINGLE_FRAGMENT || frg->mode == WS_LAST_FRAGMENT)
                signalResponseSent();

            // pop fragment and free memory only if lws_write was successful
            send_queue.pop();
            delete(frg);
        }
    }
    pthread_mutex_unlock(&send_queue_mutex);
}
neoben
  • 743
  • 12
  • 30