我有一个命令行Dart脚本客户端在dart上进行交互:io websocket与Jetty服务器交互。我实现了一个自定义消息子协议,它使用反射(两边)使用二进制编码将Dart对象与Jetty中的Java对象交换。PODO -> Uint8List -> -> ByteBufer -> POJO (并反向返回)。本地往返单元测试在任何一方(即PODO -> Uint8List -> PODO;POJO -> ByteBuffer -> POJO)上都正确执行。我使用一系列简单的“string”交换来测试与不同服务端点的连接。从Dart到Jetty的传输可以工作,但是响应数据虽然收到正确,但产生了一种奇怪的类型,我不理解,解码器也不把它理解为Uint8List、ByteBuffer等。
虽然我不能轻易地将其提取为一个小示例,但下面是相关的代码和一些输出:
Dart客户端:
WebSocket.connect(url).then((WebSocket socket) {
_log.finer('connected');
_websocket = socket
..listen(_onResponse, onError: (e, StackTrace st) => print('Session error: $e; $st'));
...
}
_onResponse(data) {
print('response raw data: $data');
InstanceMirror im = reflect(data);
print('instance: $im');
...
decode(data)
}
decode(Uint8List data) {
var b = data.buffer;
ByteData bd = new ByteData.view(b);
int offset = 0;
const ENDIANNESS = Endianness.LITTLE_ENDIAN;
int msgLength = bd.getInt32(offset, ENDIANNESS); // is 6645122; should be 101
...
}输出:
response raw data: [101, 0, 0, 0, ...]
instance: InstanceMirror on Instance of '_Uint8ArrayView'IntelliJ调试器显示:
data = {List[id=1]} size = 101
> im = {_LocalInstanceMirror[id=2]} InstanceMirror on Instance of '_Uint8ArrayView'
_reflectee = {List[id=1]}
_type = null
hasReflectee = true发布于 2014-12-28 21:26:55
“data.buffer”访问的缓冲区是支持“data”引用的Uint8List视图的内部缓冲区。传输的有效载荷--我想用ByteData视图包装的东西--被一些字节抵消到这个缓冲区中。有效负载的“偏移”可以通过“数据”对象的“offsetInBytes”属性来确定。对decode()的以下更改使使用ByteData API解码负载字节数组的各个片段成为可能:
int offset = data.offsetInBytes; // sets offset to the starting position of the payload
int msgLength = bd.getInt32(offset);
double somethingElse = bd.getFloat64(offset+4);
// etc.发布于 2014-12-28 09:54:44
Dart支持一般的ByteBuffer类型,它只是表示字节的列表,如您在这里所看到的:
由于ByteBuffer类是抽象,因此可以通过接收ByteBuffer对象或实例化新列表来创建列表。列表通常是固定长度的,使用它是很困难的。这就是为什么可以从视图创建ByteBuffer的原因。视图表示ByteBuffers字节的子集,由offset和length提供,它们也可能是整个缓冲区。
让我们看一个小例子:
import 'dart:typed_data';
void main() {
Uint8List data8 = new Uint8List.fromList([1,2,3,4,5,6,256]);
Uint16List data16 = new Uint16List.fromList([1,2,3,4,5,6,256]);
print(data8);
print(data16);
print(data8.buffer.lengthInBytes);
print(data16.buffer.lengthInBytes);
print(data16.buffer.asUint8List());
print(data16.buffer.asUint16List());
}这给了你:
[1, 2, 3, 4, 5, 6, 0] // List
[1, 2, 3, 4, 5, 6, 256] // List
7
14
[1, 0, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 0, 1] // View
[1, 2, 3, 4, 5, 6, 256] // View这意味着: ByteBuffer是一些抽象类,它为您提供了接口和基本功能,您可以从缓冲区获得视图,以便在需要时访问数据。
https://stackoverflow.com/questions/27674032
复制相似问题