通过 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)
在我的项目中,我使用 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)