Ich habe ein Problem, wo ich eine INT32 an eine andere Anwendung senden muss, aber von was ich gelesen habe, messachepack.putInt und messagepack.putLong wird versuchen, dies in UINT32 zu optimieren, die Probleme verursacht die empfangende Anwendung.Wie packe ich ein INT32 in mein MessagePack mit Java?
Die empfangende Anwendung mir die Fehlermeldung
decode error, skipping message. msgp: attempted to decode type "uint" with method for "int"
ich mit der Abhängigkeit
<dependency>
<groupId>org.msgpack</groupId>
<artifactId>msgpack-core</artifactId>
<version>0.8.13</version>
</dependency>
Jemand anderes hatte das gleiche Problem und erklärte, die Lösung für sie bin mit Maven geben war wie
folgt"OK, so dass wir das Problem gefunden haben, scheint es, als ob metricTank die Eigenschaft time des Nachrichtenobjekts benötigt, um als IN serialisiert zu werden T32, aber die packInt (oder packLong) wird immer versuchen, es in UINT32 zu optimieren, was MetrikTank nicht mag. also mussten wir addPayload verwenden und MessagePacker.Code.INT32 und dann die eigentlichen 4 Bytes der time-Eigenschaft serialisieren. "
Aber ich bin nicht sicher, was zu tun ist, und ich bin nicht in der Lage, die OP zu kontaktieren.
Ich habe folgendes versucht, aber es funktioniert nicht
ByteBuffer buf = ByteBuffer.allocate(1 + Long.BYTES);
buf.put(MessagePack.Code.INT32);
buf.putLong(md.time);
packer.addPayload(buf.array());
Die Bytes Array muss 5 sein in der Länge, ist erste Byte der Kopfzeile, wobei 0xd2 und die anderen 4 Bytes müssen den Wert
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeLong(md.time);
dos.close();
byte[] longBytes = baos.toByteArray();
ByteBuffer lBytes = ByteBuffer.allocate(4);
for (int i = 0; i < 4; i++) {
lBytes.put(longBytes[i]);
}
ByteBuffer buf = ByteBuffer.allocate(5);
buf.put((byte) 0xd2);
buf.put(lBytes.array());
Th sein, Es erzeugt keinen Fehler, aber der Zeitwert ist falsch, wenn er empfangen wird.
Könnte mir jemand zeigen, wie ich ein INT32 in mein MessagePack anstelle von UINT32 packen kann oder mir zeigen, wie ich die Daten richtig verpacken kann, damit sie auf der empfangenden Anwendung korrekt entpackt wird?
Die empfangende Anwendung ist in Go geschrieben und verwendet die tinylib msgp Bibliothek, die Daten
// ReadInt64Bytes tries to read an int64
// from 'b' and return the value and the remaining bytes.
// Possible errors:
// - ErrShortBytes (too few bytes)
// - TypeError (not a int)
func ReadInt64Bytes(b []byte) (i int64, o []byte, err error) {
l := len(b)
if l < 1 {
return 0, nil, ErrShortBytes
}
lead := b[0]
if isfixint(lead) {
i = int64(rfixint(lead))
o = b[1:]
return
}
if isnfixint(lead) {
i = int64(rnfixint(lead))
o = b[1:]
return
}
switch lead {
case mint8:
if l < 2 {
err = ErrShortBytes
return
}
i = int64(getMint8(b))
o = b[2:]
return
case mint16:
if l < 3 {
err = ErrShortBytes
return
}
i = int64(getMint16(b))
o = b[3:]
return
case mint32:
if l < 5 {
err = ErrShortBytes
return
}
i = int64(getMint32(b))
o = b[5:]
return
case mint64:
if l < 9 {
err = ErrShortBytes
return
}
i = getMint64(b)
o = b[9:]
return
default:
err = badPrefix(IntType, lead)
return
}
}
Dieser überprüft die erste Byte zu dekodieren, und, wenn das erste Byte zu mint32 gleich der ist 0xd2, dann werden die nächsten vier Bytes gelesen, was der Wert der langen ist getmint32
func getMint32(b []byte) int32 {
return (int32(b[1]) << 24) | (int32(b[2]) << 16) | (int32(b[3]) << 8) | (int32(b[4]))
}