跨平台使用时的安慰请求 - 响应问题(C#和JAVA)

时间:2015-10-14 09:33:03

标签: solace solace-mq

我正试图在Solace中实现请求 - 响应。

然而,RR-Requestor是用C#编写的,而RR-Responder的代码是用JAVA编写的。

我有两个问题:

  1. Solace C#API成功发送消息后,它将被JAVA应用程序接收。我碰巧在BytesXMLMessage结构中收到消息。 如何将消息转换为String? message.dump()给了我全部细节。

  2. 当我发送回复消息时,.NET应用程序会收到带有一些其他不需要的字符的消息。

  3. JAVA方面使用的代码:

        //After session is created
        XMLMessageConsumer consumer = session.getMessageConsumer(new RequestHandler());
        XMLMessageProducer producer = session.getMessageProducer(new PrintingPubCallback());
        consumer.start();
        session.addSubscription(
                JCSMPFactory.onlyInstance().createTopic("Test_Response_Queue"),
                true);
        class RequestHandler implements XMLMessageListener {
    
        private void sendReply(BytesXMLMessage request, BytesXMLMessage reply)
                throws JCSMPException {
    
            producer.sendReply(request, reply);
    
        }
    
        public void onException(JCSMPException arg0) {
            // TODO Auto-generated method stub
    
        }
    
        public void onReceive(BytesXMLMessage message) {
            System.out.println("Received request message, trying to parse it");
    
            System.out.println(message.dump());
    
            try {
    
                TextMessage textMessage = JCSMPFactory.onlyInstance()
                        .createMessage(TextMessage.class);
    
                final String text = "Reply from JAVA, text message!!";
                textMessage.setText(text);
    
                sendReply(message, textMessage);
    
            } catch (JCSMPException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
        }
    

    在.NET方面

                // Create the request message
            IMessage requestMessage = ContextFactory.Instance.CreateMessage();
            requestMessage.Destination = ContextFactory.Instance.CreateTopic("Test_Response_Queue");
            requestMessage.DeliveryMode = MessageDeliveryMode.Direct; /* explicitly set to MessageDeliveryMode.Direct */
            //IStreamContainer stream = SDTUtils.CreateStream(requestMessage, 256);
            //stream.AddString("Hello from Linux!!");
            requestMessage.BinaryAttachment = Encoding.ASCII.GetBytes("Hello from Linux!!");
    
            // Send the request message to the service or RRDirectReplier
            IMessage replyMessage = null;
            int timeout = 2000; /* 2 secs*/
            Console.WriteLine("\nSending  request message, waiting for {0} msecs for a reply (make sure that RRDirectReply is running) ...", timeout);
    
            if (session.SendRequest(requestMessage, out replyMessage, 2000) == ReturnCode.SOLCLIENT_OK)
            {
                // Got a reply, format and print the response message
                Console.WriteLine("\nGot reply message");
                String str = Encoding.ASCII.GetString(replyMessage.BinaryAttachment);
                Console.WriteLine(str);
            }
            else
            {
                Console.WriteLine("Request failed");
            }
            if (requestMessage != null)
            {
                // It is a good practice to dispose of messages once done using them
                requestMessage.Dispose();
            }
    

    回复包含收到的字符串中的其他字符。 见下图。

    enter image description here

    有什么想法吗?

    感谢。

2 个答案:

答案 0 :(得分:3)

如果您收到的消息是TextMessage,请尝试以下操作:

if (message instanceof TextMessage) {
    String text = ((TextMessage) message).getText();
} 
//otherwise retrieve the attachment buffer like this
else {
    byte[] body = message.getAttachmentByteBuffer().array();
    //and convert to String
    String text = new String(body);
}

您可能在回复消息的开头看到了一个额外的字符,因为您正在创建一个TextMessage作为回复。 TextMessage在附件的开头包含一些额外的字节,以将其标记为TextMessage,并包含文本的长度。您应该在.NET中使用相应的类,如TextMessage,为您进行解析。

答案 1 :(得分:3)

有几种方法可以在不同的API之间发送/接收字符串,这里有两种可能的方法。

1。将字符串转换为字节数组,并将其作为二进制有效负载附加到Solace消息。

.NET发送:

IMessage message = ContextFactory.Instance.CreateMessage();
message.Destination = topic;
message.BinaryAttachment = Encoding.UTF8.GetBytes("My .NET String");
session.Send(message);

Java接收:

// assuming that message is a reference to a received message
if(message.getAttachmentByteBuffer() != null) {
    byte[] messageBinaryPayload = message.getAttachmentByteBuffer().array();
    try {
        String myReceivedText = new String(messageBinaryPayload, "UTF-8");
        System.out.println("Received String = " + myReceivedText);
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
}
else {
    // No binary attachment in message - application needs to decide what to do next.
}

Java发送:

String myJavaString = "My Java String";
BytesXMLMessage message = JCSMPFactory.onlyInstance().createMessage(BytesXMLMessage.class);
message.writeAttachment(myJavaString.getBytes(Charset.forName("UTF-8")));
producer.send(message, topic);

.NET接收:

// assuming that message is a reference to a received message
byte[] messageBinaryPayload = message.BinaryAttachment;

if(messageBinaryPayload != null) {
    string myReceivedString = System.Text.Encoding.UTF8.GetString(messageBinaryPayload);
    Console.WriteLine("Received String = " + myReceivedString);
}
else {
    // No binary attachment in message - application needs to decide what to do next.
}

2。发送和接收字符串作为TextMessage

.NET发送:

IMessage message = ContextFactory.Instance.CreateMessage();
message.Destination = topic;
SDTUtils.SetText(message, "My .NET String");
session.Send(message);

Java接收:

// assuming that message is a reference to a received message
if (message instanceof TextMessage) {
    String myReceivedString = ((TextMessage) message).getText();
    System.out.println("Received String = " + myReceivedString);
} 
else {
    // Message is not a TextMessage - application needs to decide what to do next.
}

Java发送:

TextMessage message = JCSMPFactory.onlyInstance().createMessage(TextMessage.class);
message.setText("My Java String");
producer.send(message, topic);

.NET接收:

// assuming that message is a reference to a received message
String myReceivedString = SDTUtils.GetText(message);
if (myReceivedString != null) {
    // Message is an TextMessage
    Console.WriteLine("Received String = " + myReceivedString);
}
else {
    // Message is not a TextMessage - application needs to decide what to do next.
}