|
Every .NET example I have seen uses code similar to the following to retrieve messages:
...IMessage m... BinaryReader reader = new BinaryReader(m.Body, Encoding.UTF8); byte[] body = new byte[m.Body.Length - m.Body.Position]; reader.Read(body, 0, body.Length); ASCIIEncoding enc = new ASCIIEncoding(); string message = enc.GetString(body); Isn't there a way for me to access fields of a message using a more type safe way: m.getFloat("nameoffloatfield"); m.getString("nameofstringfield"); Instead of pointing out flaws, I am actually trying to write a utility class which will let users of .NET qpid access messages through a clean event based interface...but in order to get there I need the lower layer to be a bit saner :) Any quick examples of how I retrieve a couple of attributes of different types? Thanks |
|
Looks like I can use the following:
IMessage m = ... ... Console.WriteLine("Message Received3: " + m.ApplicationHeaders["symbol"]); Console.WriteLine("Message Received3: " + m.ApplicationHeaders["symbol"].GetType()); Console.WriteLine("Message Received3: " + m.ApplicationHeaders["price"]); Console.WriteLine("Message Received3: " + m.ApplicationHeaders["price"].GetType()); ... Which prints the following: Message Received3: USDEUR Message Received3: System.String Message Received3: 0.7551 Message Received3: System.Double Perfect! I now recall that one of the developers pointed this out in an earlier message. Perhaps this could be used in the examples as well?
|
|
Here is my attempt at a simpler C# client class (I normally develop Java, so please excuse any missing C-sharpisms). The point here is to propose my idea, rather than providing a full-fledged client (which would require greater understanding of qpid than I currently posses):
This is how a user to could subscribe to a topic: QpidClient qpid = new QpidClient("<host>"); qpid.subscribe("md.lsps").onMessage += (m) => { Console.WriteLine("===" + m["symbol"] + "==="); }; Here is the code that implements this: using System; using System.Collections.Generic; using System.Linq; using System.Text; using org.apache.qpid.client; using org.apache.qpid.transport; namespace SharpOMS { //Author: Shahbaz Chaudhary //License: Do what you like class QpidClient { public string host { get; private set; } public int port { get; private set; } private ClientSession session; public QpidClient(string host) : this(host, 5672) { } public QpidClient(string host, int port) : this(host, port, "test","guest","guest"){} public QpidClient(string host, int port, string virtualhost, string username, string password) { this.host = host; this.port = port; Client connection = new Client(); connection.connect(host, port, virtualhost, username, password); session = connection.createSession(60000);//exipration? } public QpidEvent subscribe(string routingKey) { //somehow generate a random queue name string generatedQueueName = DateTime.Now.Ticks + "" + (new Random()).Next(100000); return subscribe(generatedQueueName, routingKey); } public QpidEvent subscribe(string queueName, string routingKey) { return subscribe(queueName, routingKey, Option.AUTO_DELETE); } public QpidEvent subscribe(string queue , string routingKey, params Option[] options) { QpidEvent qe = new QpidEvent(); session.queueDeclare(queue, options); session.exchangeBind(queue, "amq.topic", routingKey); session.attachMessageListener(qe,queue); session.messageSubscribe(queue); return qe; } } public class QpidEvent : IMessageListener { public event Action<Dictionary<String, Object>> onMessage; public void messageTransfer(IMessage m) { if (onMessage != null) onMessage(m.ApplicationHeaders); } } } |
|
In reply to this post by falconair
Hi,
What you were describing in your first mail is the current way to access the message body. We may want to simplify that by using some less generic message types like a text message. Regarding the headers, there are some examples in our tests. I believe that test.interop.ApplicationHeaders.cs does what you want. Arnaud falconair wrote: > Looks like I can use the following: > IMessage m = ... > ... > Console.WriteLine("Message Received3: " + m.ApplicationHeaders["symbol"]); > Console.WriteLine("Message Received3: " + > m.ApplicationHeaders["symbol"].GetType()); > Console.WriteLine("Message Received3: " + m.ApplicationHeaders["price"]); > Console.WriteLine("Message Received3: " + > m.ApplicationHeaders["price"].GetType()); > ... > > Which prints the following: > Message Received3: USDEUR > Message Received3: System.String > Message Received3: 0.7551 > Message Received3: System.Double > > Perfect! I now recall that one of the developers pointed this out in an > earlier message. Perhaps this could be used in the examples as well? > > > falconair wrote: > >> Every .NET example I have seen uses code similar to the following to >> retrieve messages: >> ...IMessage m... >> BinaryReader reader = new BinaryReader(m.Body, Encoding.UTF8); >> byte[] body = new byte[m.Body.Length - m.Body.Position]; >> reader.Read(body, 0, body.Length); >> ASCIIEncoding enc = new ASCIIEncoding(); >> string message = enc.GetString(body); >> >> Isn't there a way for me to access fields of a message using a more type >> safe way: >> m.getFloat("nameoffloatfield"); >> m.getString("nameofstringfield"); >> >> Instead of pointing out flaws, I am actually trying to write a utility >> class which will let users of .NET qpid access messages through a clean >> event based interface...but in order to get there I need the lower layer >> to be a bit saner :) >> >> Any quick examples of how I retrieve a couple of attributes of different >> types? >> Thanks >> >> > > |
|
In reply to this post by falconair
falconair wrote:
> Here is my attempt at a simpler C# client class (I normally develop Java, so > please excuse any missing C-sharpisms). The point here is to propose my > idea, rather than providing a full-fledged client (which would require > greater understanding of qpid than I currently posses): > > This is how a user to could subscribe to a topic: > > QpidClient qpid = new QpidClient("<host>"); > qpid.subscribe("md.lsps").onMessage += (m) => { Console.WriteLine("===" + > m["symbol"] + "==="); }; > > Don't you want to let the user access the message body? Maybe we can bind the message body with the key "messageBody"? Arnaud > Here is the code that implements this: > > using System; > using System.Collections.Generic; > using System.Linq; > using System.Text; > using org.apache.qpid.client; > using org.apache.qpid.transport; > > namespace SharpOMS > { > //Author: Shahbaz Chaudhary > //License: Do what you like > class QpidClient > { > public string host { get; private set; } > public int port { get; private set; } > > private ClientSession session; > > public QpidClient(string host) : this(host, 5672) { } > public QpidClient(string host, int port) : this(host, port, > "test","guest","guest"){} > > public QpidClient(string host, int port, string virtualhost, string > username, string password) > { > this.host = host; > this.port = port; > > Client connection = new Client(); > connection.connect(host, port, virtualhost, username, password); > session = connection.createSession(60000);//exipration? > } > > public QpidEvent subscribe(string routingKey) > { > //somehow generate a random queue name > string generatedQueueName = DateTime.Now.Ticks + "" + (new > Random()).Next(100000); > return subscribe(generatedQueueName, routingKey); > } > > public QpidEvent subscribe(string queueName, string routingKey) > { > return subscribe(queueName, routingKey, Option.AUTO_DELETE); > } > > public QpidEvent subscribe(string queue , string routingKey, params > Option[] options) > { > QpidEvent qe = new QpidEvent(); > session.queueDeclare(queue, options); > session.exchangeBind(queue, "amq.topic", routingKey); > session.attachMessageListener(qe,queue); > session.messageSubscribe(queue); > return qe; > } > } > > public class QpidEvent : IMessageListener > { > public event Action<Dictionary<String, Object>> onMessage; > > public void messageTransfer(IMessage m) > { > if (onMessage != null) onMessage(m.ApplicationHeaders); > } > } > > } > > --------------------------------------------------------------------- Apache Qpid - AMQP Messaging Implementation Project: http://qpid.apache.org Use/Interact: mailto:[hidden email] |
|
If the callback method returns IMessage itself, then the user has to get application headers out of it, then get at the actual attributes. That looks unintuitive to me since the attributes of message are the most important piece of the message. Bypassing IMessage completely also doesn't make sense since it does contain useful information. Perhaps somehow making IMessage a type of dictionary directly (rather than making ApplicationHeaders a member of IMessage) will do the trick?
|
|
falconair wrote:
> If the callback method returns IMessage itself, then the user has to get > application headers out of it, then get at the actual attributes. That > looks unintuitive to me since the attributes of message are the most > important piece of the message. According to me a message has a body and some properties or headers; Note that this is the case with JMS. > Bypassing IMessage completely also doesn't > make sense since it does contain useful information. Perhaps somehow making > IMessage a type of dictionary directly (rather than making > ApplicationHeaders a member of IMessage) will do the trick? > > I don't think we should change IMessage as it represents an AMQP message. We can however, and I thought this is what you were after , introduce a wrapper around IMessage that would hide the AMQP specificities. This wrapper could be if you wish a Dictionary that may provide access to the message body through a specific key. What do you think? Arnaud --------------------------------------------------------------------- Apache Qpid - AMQP Messaging Implementation Project: http://qpid.apache.org Use/Interact: mailto:[hidden email] |
|
(sorry for the late response, thought I already replied)
As a user of qpid, I am most interested in getting at the content of a message immediately (not having to deal with attributes in terms of byte arrays, not having to unwrap layers of wrappings). A wrapper around IMessage could do this nicely, as long as it doesn't hide the interesting content in deeper layers.
|
|
Hi,
I have create a JIRA for this issue: see *QPID-1620 <https://issues.apache.org/jira/browse/QPID-1620>. *It would be nice to comment on this JIRA so we can make a decision and add the new API. Thanks Arnaud falconair wrote: > (sorry for the late response, thought I already replied) > > As a user of qpid, I am most interested in getting at the content of a > message immediately (not having to deal with attributes in terms of byte > arrays, not having to unwrap layers of wrappings). A wrapper around > IMessage could do this nicely, as long as it doesn't hide the interesting > content in deeper layers. > > > Arnaud Simon wrote: > >> I don't think we should change IMessage as it represents an AMQP >> message. We can however, and I thought this is what you were after , >> introduce a wrapper around IMessage that would hide the AMQP >> specificities. This wrapper could be if you wish a Dictionary that may >> provide access to the message body through a specific key. What do you >> think? >> >> Arnaud >> >> >> --------------------------------------------------------------------- >> Apache Qpid - AMQP Messaging Implementation >> Project: http://qpid.apache.org >> Use/Interact: mailto:[hidden email] >> >> >> >> > > |
| Powered by Nabble | Edit this page |
