libwebsocket:无法写入大于7160字节的帧

libwebsocket: unable to write frame bigger than 7160 bytes

本文关键字:7160 字节 大于 libwebsocket      更新时间:2023-10-16

我正在解决一个我无法理解的WebSocket问题
请使用以下代码作为参考:

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;
    }

当我尝试发送大于7160字节的数据时,我总是收到相同的错误,例如部分写入:7160<8000
你对这种行为有什么解释吗
我已经分配了一个为有效负载保留8000字节的缓冲区,所以我希望能够发送8K的最大数据量,但7160(字节)似乎是我可以发送的最大数据数量
感谢您的帮助!

我在旧版本的libwebsocket中遇到过类似的问题。虽然我没有监控限制,但它基本上是一样的:n < write_len。我认为我的限制要低得多,低于2048B,而且我知道相同的代码在新版本的libwebsocket(在不同的机器上)中运行良好。

由于Debian Jessie在存储库中没有lws v1.6,所以我从github源代码构建了它。考虑升级,它可能有助于解决您的问题。小心,他们已经更改了api。它主要是将方法的名称从libwebsocket_*重命名为lws_*,但也更改了一些参数。检查此pull请求,该请求将样板文件libwebsockets服务器迁移到版本1.6。这些更改大多会影响您的代码。

我们解决了将libwebsockets更新到1.7.3版本的问题
我们还使用自定义回调优化了代码,当通道可写时调用

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);
}