How to consume MSMQ service - msmq

I want to consume msmq service. But unable to send message to queue.
Here is my code.
System.Messaging.MessageQueue msmQ = new System.Messaging.MessageQueue("net.msmq://myServerName/private/MyQueueName");
msg ="<nodeDetails><node>Node1</node></nodeDetails>";//Dummy value. it is XML structure consist of multiple node
msmQ.Send(msg);
It gives me an error on msmQ.Send(msg)
Length cannot be less than zero. Parameter name: length
The following things are installed on my m/c:
Microsoft Message Queue(MSMQ)Server
Window Activation Process
Also when I tried as
bool msmQExits = MessageQueue.Exists("net.msmq://myServerName/private/MyQueueName");
it gives "Path syntax is invalid". I am not able to get anything on it.
I just have a msmq URL net.msmq://myServerName/private/MyQueueName.
How can I consume such URL and send my message to "MyQueueName"?

Change your queue name to this:
var queueName = #"FormatName:DIRECT=HTTP://URLAddressSpecification/net.msmq://myServerName/private/MyQueueName";
And you cannot check if a remote query exists by MessageQueue.Exists method. It will always throw an exception.
You can check these links for more info:
MSMQ FormatName
Checking if a remote query exists
Also, the problem is not with the message you see that length is less than 0. If you go deeper and check the stack trace you’ll see that your queue name has an invalid format. It tries to find FORMAT occurrence inside your queue name, doesn’t find it and Substring() method returns -1 there.
Stacktrace:
at System.String.Substring(Int32 startIndex, Int32 length)
at System.Messaging.MessageQueue.ResolveFormatNameFromQueuePath(String queuePath, Boolean throwException)
at System.Messaging.MessageQueue.get_FormatName()
at System.Messaging.MessageQueue.SendInternal(Object obj, MessageQueueTransaction internalTransaction, MessageQueueTransactionType transactionType)
at System.Messaging.MessageQueue.Send(Object obj)
at MessagingTest.Program.SendMessage(String str, Int32 x) in c:\Users\ivan.yurchenko\Documents\Visual Studio 2013\Projects\MSMQTestProjects\MessagingTest\MessagingTest\Program.cs:line 21
at MessagingTest.Program.<Main>b__1() in c:\Users\ivan.yurchenko\Documents\Visual Studio 2013\Projects\MSMQTestProjects\MessagingTest\MessagingTest\Program.cs:line 38
at System.Threading.Tasks.Task.InnerInvoke()
at System.Threading.Tasks.Task.Execute()

Here is an example for how to consume the service.
It has Wcf Service,Physical MSMQ, and the client project. So you have to have a WCF service to receive the message and msmq to store the message and a client to send the message.
http://www.codeproject.com/Articles/326909/Creating-a-WCF-Service-with-MSMQ-Communication-and

Related

Bidirectional communication of Unix sockets

I'm trying to create a server that sets up a Unix socket and listens for clients which send/receive data. I've made a small repository to recreate the problem.
The server runs and it can receive data from the clients that connect, but I can't get the server response to be read from the client without an error on the server.
I have commented out the offending code on the client and server. Uncomment both to recreate the problem.
When the code to respond to the client is uncommented, I get this error on the server:
thread '' panicked at 'called Result::unwrap() on an Err value: Os { code: 11, kind: WouldBlock, message: "Resource temporarily unavailable" }', src/main.rs:77:42
MRE Link
Your code calls set_read_timeout to set the timeout on the socket. Its documentation states that on Unix it results in a WouldBlock error in case of timeout, which is precisely what happens to you.
As to why your client times out, the likely reason is that the server calls stream.read_to_string(&mut response), which reads the stream until end-of-file. On the other hand, your client calls write_all() followed by flush(), and (after uncommenting the offending code) attempts to read the response. But the attempt to read the response means that the stream is not closed, so the server will wait for EOF, and you have a deadlock on your hands. Note that none of this is specific to Rust; you would have the exact same issue in C++ or Python.
To fix the issue, you need to use a protocol in your communication. A very simple protocol could consist of first sending the message size (in a fixed format, perhaps 4 bytes in length) and only then the actual message. The code that reads from the stream would do the same: first read the message size and then the message itself. Even better than inventing your own protocol would be to use an existing one, e.g. to exchange messages using serde.

Azure Service Bus Queue gives control characters in fetched message

I am using BizTalk Server SB-Messaging adapter to retreive messages from Azure Service Bus Queue. I have successfully managed to send message to queue myself (using same adapter), and retreive message from queue and do further processing.
Problem arises when a 3rd party software supplier is sending messages to the queue, and for BizTalk Server to retreive and process message. I then receive the following additional "header"-information and control characters in the beginning of the message:
In text: #ACKstringBShttp://schemas.microsoft.com/2003/10/Serialization/?$SOH
Seems like there is some sort of enveloped message, including headers to handle ACKnowledgement of the message to the queue.
SB-Messaging adapter gave following initial error message:
"The WCF service host at address has faulted and as a result no
more messages can be received on the corresponding receive location.
To fix the issue, BizTalk Server will automatically attempt to restart
the service host."
And, another error message:
"No Disassemble stage components can recognize the data."
Did anyone hit this problem before, and, what can be the cause of the problem? Can character encoding be a possible cause of this problem?
Here comes the feedback!
Turned out 3rd party software supplier had a setting to send message as stream, instead of string. Turns out it is a .Net application using BrokeredMessage object. Using string makes message serialized, and meta-data is added to the message. Using stream, no such serialization takes place, and message is kept untouched.
So, problem was using string and automatic serialization when sending to Service Bus Queue.
I have legacy Microsoft.ServiceBus.Messaging clients sending BrokeredMessage Xml content as <string> and I want to receive using the latest Microsoft.Azure.ServiceBus library and Message type.
Using Encoding.UTF8.GetString(message.Body) I get a unusable string prefaced with
#\u0006string\b3http://schemas.microsoft.com/2003/10/Serialization/��#
My approach is to explicitly use XmlDictionaryReader binary deserialization to undo the hidden serialization magic from the legacy library
private static string GetMessageBodyHandlingLegacyBrokeredMessage(Message message)
{
string str = null;
if (message.ContentType == null)
{
using (var reader = XmlDictionaryReader.CreateBinaryReader(
new MemoryStream(message.Body),
null,
XmlDictionaryReaderQuotas.Max))
{
var doc = new XmlDocument();
doc.Load(reader);
str = doc.InnerText;
}
}
else
throw new NotImplementedException("Unhandled Service Bus ContentType " + message.ContentType);
return str;
}
References
https://learn.microsoft.com/en-us/azure/service-bus-messaging/service-bus-messages-payloads#payload-serialization
https://carlos.mendible.com/2016/07/17/step-by-step-net-core-azure-service-bus-and-amqp/

TCP Socket connection- Unable to read data sent from external client even after serializing through ByteArrayLengthHeaderSerializer

I have implemented TCP socket server which accepts incoming XML messages from client. I could send messages through telnet.
But when I am trying to establish connection and send message through python script, I was getting IOException:CRLF not found before max message length: 2048.So I have added ByteArrayLengthHeaderSerializer to serialize and deserialize, but now I am getting below error.
IOException:Message length 1014132591 exceeds max message length: 2048
Though I am increasing the max message length I am getting IOException:Stream closed after 46 of 1014132591
Could someone let me know how to fix the issue.
final AbstractServerConnectionFactory crLfServer = context.getBean(AbstractServerConnectionFactory.class);
ByteArrayLengthHeaderSerializer serializer = new ByteArrayLengthHeaderSerializer();
serializer.setMaxMessageSize(1000 * 1024);
crLfServer.setSerializer(serializer);
crLfServer.setDeserializer(serializer);
I have implemented using Spring Integration.Below is the snippet for my inbound adapter
#Bean
public TcpReceivingChannelAdapter inboundAdapter(AbstractServerConnectionFactory connectionFactory) {
System.out.println("Creating inbound adapter");
TcpReceivingChannelAdapter inbound = new TcpReceivingChannelAdapter();
inbound.setConnectionFactory(connectionFactory);
//inbound.
inbound.setOutputChannel(fromTcp());
return inbound;
}
I think might be better to send exactly that CRLF in your script after the message. That will be exactly delimiter for the messages to deserialize. This is one what is used by the mentioned Telnet. However you need to come back to the default deserializer in the connection factory configuration.

NETTY 4.1.4: TCP Socket Server which replies back towards clients after processing requests

i'm new to Netty and intend to create a tcp socket server which reads the info of each client and replies back towards client before processing requests immediately ,i.e. sort of an acknowledgement towards client as and when the message enters overriden channelRead method of ChannelInboundHandlerAdapter class.
Please guide me in the above specified objective.
i'm currently trying the basic netty 4.1.4 echo server example however i wanted server to send back acknowledgement to the client so i updated channelread method as follows :
#Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ctx.write(msg);
ChannelFuture cf = ctx.channel().write("FROM SERVER");
System.out.println("Channelfuture is "+cf);
}
and the output obtained was as follows:
Channelfuture is DefaultChannelPromise#3f4ee9dd(failure: java.lang.UnsupportedOperationException: unsupported message type: String (expected: ByteBuf, FileRegion))
I understand the error that it is expecting bytebuf but how do i achieve it? also, whether this method would be able to send out acknowledgement towards client
You can use String.getBytes(Charset) and Unpooled.wrappedBuffer(byte[]) to convert to ByteBuf.
ChannelFuture cf = ctx.channel()
.write(Unpooled.wrappedBuffer("FROM SERVER".getBytes(CharsetUtil.UTF_8)));
Also note that ctx.channel().write(...); may not be what you want. Consider ctx.write(...); instead. The difference is that if your handler is a ChannelDuplexHandler it would receive a write event when you do channel().write(). Using ctx instead of channel will send the write out from your handlers point in the pipeline instead of from the end of the pipeline, which is usually what you want.

NServiceBus - message not always delivers and causing exception Cannot enlist the transaction

We are using NServiceBus on production, and in our log files we see the following error:
ERROR Our.Namespace.SomeMessageHandler [(null)] <(null)> - MethodName --> end with exception: NServiceBus.Unicast.Queuing.FailedToSendMessageException: Failed to send message to address: our.namespace.worker#somemachinename ---> System.Messaging.MessageQueueException: Cannot enlist the transaction.
at System.Messaging.MessageQueue.SendInternal(Object obj, MessageQueueTransaction internalTransaction, MessageQueueTransactionType transactionType)
at NServiceBus.Unicast.Queuing.Msmq.MsmqMessageSender.NServiceBus.Unicast.Queuing.ISendMessages.Send(TransportMessage message, Address address)
--- End of inner exception stack trace ---
at NServiceBus.Unicast.Queuing.Msmq.MsmqMessageSender.ThrowFailedToSendException(Address address, Exception ex)
at NServiceBus.Unicast.Queuing.Msmq.MsmqMessageSender.NServiceBus.Unicast.Queuing.ISendMessages.Send(TransportMessage message, Address address)
at NServiceBus.Unicast.UnicastBus.SendMessage(List`1 addresses, String correlationId, MessageIntentEnum messageIntent, Object[] messages)
at NServiceBus.Unicast.UnicastBus.SendMessage(Address address, String correlationId, MessageIntentEnum messageIntent, Object[] messages)
at NServiceBus.Unicast.UnicastBus.NServiceBus.IBus.Send(Address address, Object[] messages)
at Our.Namespace.SomeMessageHandler.MethodName(EventLogVO eventLog, IApplicationContext applContext, CreateEventLogHistory message)
The queue on the target machine exists (double checked). The strange thing here is that it doesn't happen all the time and for each message sent to that queue, but happens occasionally (which means that there are messages that arrive to that queue).
Searched and didn't find a similar case.
What am I missing here?
We recently had this error and tracked it down to be one of the following:
Database performance. We had a long running query that we tuned up, but the problem persisted.
Large transaction scope. You may be doing something that would cause too many resource managers to be involved.
MSMQ Resources. Ultimately our disk was not fast enough to perform the IO required for what we were doing with MSMQ.
I would try to track down the true source (hopefully you get some ideas from above). But if all else fails, first turn on the System.Transactions logging to see if it is truly a timeout. If it is, then use this section in the app.config
I had this happen to me in a handler that took over a minute to complete,
I ended up increasing the timeout by adding this to the app.config
<system.transactions>
<defaultSettings timeout="00:05:00"/>
</system.transactions>
As per this:
https://erictummers.wordpress.com/2014/05/28/cannot-enlist-the-transaction/
Additionally, I changed machine config as per this post:
http://blogs.msdn.com/b/ajit/archive/2008/06/18/override-the-system-transactions-default-timeout-of-10-minutes-in-the-code.aspx
I also wrote a quick app that edits the machine.configs:
https://github.com/hfortegcmlp/MachineConfigEditor