通过 WebRTC 数据通道发送和接收对象

Send and receive objects through WebRTC data channel

在我的项目中,我使用 WebRTC 在使用 aiortc 包的 2 个客户端之间进行连接。

我正在使用 this example code 并且它有效,但我似乎无法在数据通道中发送非字符串数据。

这是我在数据通道中发送的内容(修改了client.js文件中start函数中的代码):

dc.onopen = function() {
    dataChannelLog.textContent += '- open\n';
    dcInterval = setInterval(function() {
        let message = new DataObject(/*All the parameters*/);
        dataChannelLog.textContent += '> ' + message + '\n';
        dc.send(message);
    }, 100);
};

其中 DataObject 是我创建的 class,其中包含我要发送的数据。

Python 客户端接收 [object Object] 作为字符串。我预计它将发送表示我可以在 Python 中转换回正常 class.

的对象的字节

我知道解决这个问题的方法是将对象转换为字符串格式(如 JSON),但我不想这样做,因为我发送对象的频率很高(而且每个对象其中包含一个大数组),我相信这会导致性能问题。

所以我的问题是,如何在不转换为字符串的情况下通过数据通道发送对象?

编辑:如果有帮助,我可以使用数组而不是对象来表示我的数据。但同样,它仍然作为字符串发送和接收。

您需要某种序列化程序函数来将您的 Javascript 对象转换为字节流。这些字节不必作为文本可读。您不能只发送一个 Javascript 对象。

built-in 强大而安全的序列化程序当然是 JSON.stringify()。正如您所指出的 JSON 是一种冗长的格式。

为避免使用 JSON,您需要在 Javascript 中创建自己的序列化程序,在 Python 中创建反序列化程序。这些很可能是针对您的特定对象类型的自定义代码。为获得最佳效果,您需要将对象的属性一个一个地复制到 Uint8Array 中,然后发送它。

您没有告诉我们关于您的对象的任何信息,因此很难进一步帮助您。

如果这是我的项目,我会使用 JSON 进行所有操作,然后进行自定义序列化以提高性能。

感谢 o-jones 的详细回答。

在我的例子中,它相当简单,因为我能够将我的所有数据表示为一个数组。

我遇到的主要问题是我不知道 send 函数有一个接受 bytes array

的“重载”

意识到这一点后,我在 Javascript 中创建了一个 Float32Array 来保存我的数据并发送它。

Python 端,我读取了这些数据并使用 struct.unpack 函数将其转换为 float 数组。

类似的东西:

Javascript 边:

dc.onopen = function() {
    dataChannelLog.textContent += '- open\n';
    dcInterval = setInterval(function() {
        let dataObj = new DataObject(/*All the parameters*/);
        let data = new Float32Array(3); // Build an array (in my case 3 floats array)

        // Insert the data into the array
        data[0] = dataObj.value1;
        data[1] = dataObj.value2;
        data[2] = dataObj.value3;

        // Send the data
        dc.send(data);
    }, 100);
};

Python 边:

import struct

def message_received(message: str | bytes) -> None:
    if isinstance(message, str):
        return  # Don't handle string messages

    # Read 3 floats from the bytes array we received.
    data = struct.unpack('3f', message)