协议缓冲区作为活动Mq上的消息

时间:2011-05-24 05:29:20

标签: jms activemq protocol-buffers

我正在设计一个包含多个组件的应用程序,主要用java和python编写。 我正在考虑将“JMS-Active MQ”用作组件和“协议缓冲区”的面向消息的中间件。

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

2)我创建了一个概念验证,我在“ActiveMQ”上发送了一个“协议buff”作为消息,我在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)

我不知道出了什么问题。?

2 个答案:

答案 0 :(得分:4)

关于1),协议缓冲区的文档讨论了传输大型消息here

关于2),问题似乎是你转移book的方式。 看看the tutorial you mention如何将消息写入OutputStream。您应该使用binary one而不是TextMessage,例如首先将字节写入ByteArrayOutputStream,然后再写入message

答案 1 :(得分:1)

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

除此之外,您可以使用protobuf以及JMS上的任何其他格式。我更喜欢JSON的可读性和可扩展性,但是如果你已经在使用protobuf,这是内部系统(不是暴露给外部各方),protobuf也可以。