You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在WebRTC与libdatachannel中发送超大小限制的文件内容

解决libdatachannel发送大文件的消息大小超限问题

浏览器端WebRTC数据通道的默认消息大小限制(通常约64KB)无法修改,你需要手动将文件拆分为多个小分片发送,再在接收端重组。具体实现如下:

1. 发送端:拆分文件并分片发送

不再一次性将整个文件内容打包进JSON,而是先发送文件元数据,再分批次发送内容分片:

#include <fstream>
#include <vector>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

// 分片大小设为60KB,留足余量避免触发浏览器限制
const size_t CHUNK_SIZE = 60 * 1024;

void sendFile(std::shared_ptr<rtc::DataChannel> dc, const std::wstring& filePath) {
    // 读取文件内容
    std::ifstream file(filePath, std::ios::binary | std::ios::ate);
    if (!file.is_open()) return;
    
    std::streamsize fileSize = file.tellg();
    file.seekg(0, std::ios::beg);
    
    std::vector<char> fileBuffer(fileSize);
    if (!file.read(fileBuffer.data(), fileSize)) return;
    file.close();

    // 发送元数据:告知接收端文件基本信息
    json metadata = {
        {"Message_Type", "File_Metadata"},
        {"FileName", filePath.substr(filePath.find_last_of(L"/\\") + 1)},
        {"TotalSize", fileSize},
        {"TotalChunks", (fileSize + CHUNK_SIZE - 1) / CHUNK_SIZE} // 向上取整计算分片数
    };
    dc->send(metadata.dump());

    // 分片发送文件内容
    for (size_t i = 0; i < fileBuffer.size(); i += CHUNK_SIZE) {
        size_t chunkLen = std::min(CHUNK_SIZE, fileBuffer.size() - i);
        std::string chunkData(fileBuffer.data() + i, chunkLen);

        json chunkMsg = {
            {"Message_Type", "File_Chunk"},
            {"ChunkIndex", i / CHUNK_SIZE},
            {"IsLastChunk", (i + chunkLen) >= fileBuffer.size()},
            {"ChunkData", chunkData}
        };
        dc->send(chunkMsg.dump());
    }
}

2. 接收端(浏览器JS):重组分片

监听数据通道的message事件,先接收元数据初始化缓存,待所有分片收齐后合并为完整文件:

let fileCache = {};

dataChannel.onmessage = (event) => {
    const msg = JSON.parse(event.data);
    switch(msg.Message_Type) {
        case "File_Metadata":
            // 初始化文件缓存
            fileCache = {
                fileName: msg.FileName,
                totalSize: msg.TotalSize,
                totalChunks: msg.TotalChunks,
                receivedChunks: {},
                receivedCount: 0
            };
            break;
        case "File_Chunk":
            if (!fileCache) return;
            // 存储当前分片
            fileCache.receivedChunks[msg.ChunkIndex] = msg.ChunkData;
            fileCache.receivedCount++;

            // 检查是否所有分片已接收
            if (fileCache.receivedCount === fileCache.totalChunks) {
                // 合并所有分片
                let fileContent = "";
                for (let i = 0; i < fileCache.totalChunks; i++) {
                    fileContent += fileCache.receivedChunks[i];
                }

                // 示例:将合并后的内容转为Blob并下载
                const blob = new Blob([fileContent], {type: "application/octet-stream"});
                const url = URL.createObjectURL(blob);
                const a = document.createElement("a");
                a.href = url;
                a.download = fileCache.fileName;
                a.click();
                URL.revokeObjectURL(url);

                // 清空缓存
                fileCache = {};
            }
            break;
    }
};

注意事项

  • 分片大小建议控制在60KB以内,适配不同浏览器的默认限制。
  • 默认的可靠数据通道会自动保证分片的顺序和送达,若使用不可靠通道,需额外添加分片校验、重传逻辑。
  • 大文件发送时可通过分片发送进度,实现整体传输进度提示。

内容的提问来源于stack exchange,提问作者rumeysa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 00:40:01