2015-10-14 9 views
1

Я пытаюсь реализовать Request-Response в Solace.Проблемы с запросом на устранение неполадок при использовании на разных платформах (C# и JAVA)

Однако RR-Requestor написан на C#, тогда как код для RR-Responder написан в JAVA.

Я 2 вопроса:

  1. После того, как сообщение отправлено на # API Solace C, то полученные с помощью приложения JAVA. Я получаю сообщение в структуре BytesXMLMessage. Как преобразовать сообщение в String? message.dump() дает мне полную информацию.

  2. Когда я отправляю ответное сообщение, приложение .NET получает сообщение с некоторыми дополнительными нежелательными символами.

Код, используемый в стороне 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

Любая идея?

Спасибо.

ответ

3

Существует несколько способов отправки/получения строк между различными API-интерфейсами, а также 2 возможных метода.

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. Отправить и получить строку в виде текстового сообщения

.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. 
} 
+0

Большое спасибо @Russell Sim –

+0

Также я считаю, if (session.SendRequest (requestMessage, out r eplyMessage, 4000) == ReturnCode.SOLCLIENT_OK) {} - способ отправки сообщения. Он ждет до 4 секунд, пока сообщение для сообщения ответа не поступит. Как мы можем заставить его ждать бесконечно? Если мы не уверены, сколько времени RRRsponder собирается предпринять, чтобы ответить. –

+0

@Dixit Невозможно сделать этот метод неопределенным. Вы можете использовать огромное значение таймаута (Int32.MaxValue) для имитации неопределенного ожидания. Тем не менее, лучше использовать приложение не ждать бесконечно и на самом деле заставить его действовать через определенное время. Возможно, уведомление пользователю в порядке? Возможно, вы можете подумать о повторной отправке сообщения после определенного количества времени ожидания. –

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, который выполняет синтаксический анализ для вас.