Quantcast

c# message retreival without resorting to encodings and bytes readers?

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

c# message retreival without resorting to encodings and bytes readers?

falconair
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
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: c# message retreival without resorting to encodings and bytes readers?

falconair
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
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: c# message retreival without resorting to encodings and bytes readers?

falconair
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);
        }
    }

}
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: c# message retreival without resorting to encodings and bytes readers?

Arnaud Simon
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
>>
>>    
>
>  

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: c# message retreival without resorting to encodings and bytes readers?

Arnaud Simon
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"] + "==="); };
>
>  
Looks good to me.
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]

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: c# message retreival without resorting to encodings and bytes readers?

falconair
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?


Arnaud Simon wrote
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"] + "==="); };
>
>  
Looks good to me.
Don't you want to let the user access the message body? Maybe we can
bind the message body with the key "messageBody"?

Arnaud
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: c# message retreival without resorting to encodings and bytes readers?

Arnaud Simon
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]

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: c# message retreival without resorting to encodings and bytes readers?

falconair
(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:users-subscribe@qpid.apache.org
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: c# message retreival without resorting to encodings and bytes readers?

Arnaud Simon
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]
>>
>>
>>
>>    
>
>  

Loading...