解决跨平台使用时的请求-响应问题(C# 和 JAVA)
Solace Request-Response issues while using across platforms ( C# and JAVA )
我正在尝试在 Solace 中实现请求-响应。
但是 RR-Requestor 是用 C# 编写的,而 RR-Responder 的代码是用 JAVA 编写的。
我有 2 个问题:
消息在 Solace C# API 成功发送后,被 JAVA 应用程序接收。我碰巧收到了 BytesXMLMessage 结构中的消息。
如何将消息转换为字符串? message.dump() 给了我全部的细节。
当我发送回复消息时,.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();
}
回复在收到的字符串中包含额外的字符。
见下图。
有什么想法吗?
谢谢。
如果您收到的消息是短信,请尝试以下操作:
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 中使用相应的 class,例如为您解析的 TextMessage。
在不同的 API 之间 send/receive 字符串有多种方法,这里有 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。作为 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.
}
我正在尝试在 Solace 中实现请求-响应。
但是 RR-Requestor 是用 C# 编写的,而 RR-Responder 的代码是用 JAVA 编写的。
我有 2 个问题:
消息在 Solace C# API 成功发送后,被 JAVA 应用程序接收。我碰巧收到了 BytesXMLMessage 结构中的消息。 如何将消息转换为字符串? message.dump() 给了我全部的细节。
当我发送回复消息时,.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();
}
回复在收到的字符串中包含额外的字符。 见下图。
有什么想法吗?
谢谢。
如果您收到的消息是短信,请尝试以下操作:
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 中使用相应的 class,例如为您解析的 TextMessage。
在不同的 API 之间 send/receive 字符串有多种方法,这里有 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。作为 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.
}