协议缓冲区作为 JMS 上的消息

问题描述 投票:0回答:2

我正在设计一个具有多个组件的应用程序,主要用 Java 和 Python 编写。 我正在考虑使用 JMS 作为组件和“协议缓冲区”的面向消息的中间件。

  1. 这是继续前进的好方法吗?在我们的例子中,“消息大小”可以远远超过 10MB,协议缓冲区对于跨组件通信仍然具有优势吗?对于可以处理“海量数据”的跨平台应用程序,是否有更好的通信“协议”?

  2. 我创建了一个概念证明,发送“协议增益”作为消息。我正在使用 google 的 java 教程中的示例 proto 文件。

AddressBook.Builder book = AddressBook.newBuilder();
Person.Builder person = Person.newBuilder();
person.setName("mayank");
person.setId(2);
book.addPerson(person); 
TextMessage message = session.createTextMessage();
message.setText(book.build().toString());

在另一个 java 应用程序中,我监听此消息并尝试将其反序列化回 AddressBook 对象:

public void onMessage(Message message) {
    TextMessage msg = (TextMessage) message;
    try {
        System.out.println(msg.getText());
        CodedInputStream stream =CodedInputStream.newInstance(msg.getText().getBytes());
        AddressBook book = AddressBook.parseFrom(stream);
    }
    catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } 
}

这会导致异常:

com.google.protobuf.InvalidProtocolBufferException: While parsing a protocol message, the input ended unexpectedly in the middle of a field.  This could mean either than the input has been truncated or that an embedded message misreported its own length.
    at com.google.protobuf.InvalidProtocolBufferException.truncatedMessage(InvalidProtocolBufferException.java:49)

我不知道出了什么问题。

protocol-buffers jms
2个回答
5
投票

关于 1),protocol buffers 的文档讨论了传输大消息这里

关于2),问题似乎是你转移的方式

book
。 看一下您提到的教程如何将消息写入 OutputStream。您应该使用 binary one 而不是 TextMessage,例如首先将字节写入 ByteArrayOutputStream,然后写入 message


1
投票

主要问题是,由于某种原因,您使用的是 TextMessage 而不是正确选择 BytesMessage:protobuf 是二进制编码而不是文本编码。 如果您绝对想将 TextMessage 误用于非文本消息,则必须指定 getBytes() 使用的编码;使用的编码必须与用于将二进制有效负载转换为字节的编码相匹配。如果您使用 UTF-8,您可能已经损坏了消息...(ISO-8859-1,又名 Latin-1 实际上可以工作,因为它是单字节编码)。

除此之外,您还可以通过 JMS 使用 protobuf 以及任意数量的其他格式。我更喜欢 JSON 的可读性和可扩展性,但如果您已经在使用 protobuf,并且这是内部系统(不是暴露给外部各方的东西),protobuf 也可以工作。

© www.soinside.com 2019 - 2024. All rights reserved.