On Thu, 2017-03-30 at 12:16 +0100, Robbie Gemmell wrote:
> I cant help much on the python or cpp bits, or rabbitmq, but on the
> general 'send string' subject I think it is probably that you'll want
> to use unicode strings to get the client sending AMQP strings on the
> wire. The AMQP strings are utf8 encoded, wheres I believe python str
> type is often used for raw bytes, and the client has no way of
> knowing
> whether thats the case or not and so sends an AMQP binary value
> containing the bytes instead.

+1  - this is an old and constant source of confusion in the python
bindings. It is different between python2 and python3 - python3 fixes
the confusion, but the 2/3 difference is itself confusing.

In short: in python always use u"foo" literals, and if using strings
created outside your, explicitly convert them to unicode.

In python 2 a literal "foo" or other instance of type `str` will be
treated as bytes, a unicode string as an AMQP string. Since old python
2 code tends to assume that "foo" and u"foo" are more or less the same
you need to be careful.

In python 3 a literal "foo" or instance of `str` actually *is* unicode
and there's a new type called `bytes` for raw bytes so in pure python 3
it all works as expected. However if you write code that needs to work
on 2 & 3 you must work at the least common denominator.

> 
> Robbie
> 
> On 30 March 2017 at 09:52, Daniel Pocock <[email protected]> wrote:
> > 
> > 
> > Hi all,
> > 
> > I've recently been working on some projects involving qpid-proton
> > (C++
> > and Python variants) and rabbitmq servers and there are a couple of
> > issues I've observed, could anybody comment on these?
> > 
> > Environment
> > -----------
> > 
> > I'm running Debian jessie / stable with the qpid-proton packages
> > from
> > the Debian backports repository[1], currently version 0.14.0-
> > 4~bpo8+1
> > and rabbitmq[2] version 3.3.5-1.1+deb8u1
> > 
> > When I install the rabbitmq-server package on a host, I run these
> > commands to enable AMQP 1.0 support:
> > 
> >    apt-get install rabbitmq-server
> >    rabbitmq-plugins enable rabbitmq_amqp1_0
> >    systemctl restart rabbitmq-server
> > 
> > 
> > I've also tried installing a config file
> > /etc/rabbitmq/rabbitmq.config
> > although if I understand correctly, it is not needed and in fact
> > the
> > package doesn't install it there by default.
> > 
> > 
> > Sending to RabbitMQ with qpid-proton python
> > -------------------------------------------
> > 
> > I started with the simple_send.py[3] example and trimmed it down to
> > send
> > a single string and then stop:
> > 
> >     def on_sendable(self, event):
> >         if self.msg_body is not None:
> >             print("on_sendable !")
> >             print ("sending : %s" % (self.msg_body,))
> >             msg = Message(body=self.msg_body)
> >             event.sender.send(msg)
> >             self.msg_body = None
> > 
> > I found that the connection to RabbitMQ would be dropped and an
> > error
> > would appear in the RabbitMQ log.  I tried changing the body type
> > to a
> > dict containing a string, e.g. {'my_body':'foo'} and then it would
> > successfully pass the message to RabbitMQ but then the receiver
> > would
> > complain that it was a map and not a string.
> > 
> > I found that the problem could be fixed by adding "inferred=True"
> > to the
> > Message constructor:
> > 
> >             msg = Message(body=self.msg_body, inferred=True)
> > 
> > Below is a complete example of the error from the RabbitMQ log when
> > inferred=True is not present, the body in this case was the string
> > "foo"
> > 
> > 
> > Receiving from RabbitMQ with qpid-proton C++
> > --------------------------------------------
> > 
> > I looked at the receive example simple_recv.cpp[4] and other
> > examples
> > and noticed code like this being used to access the message body as
> > std::string:
> > 
> > proton::get<std::string>(m.body())
> > 
> > However, that didn't work for me, it threw a conversion_error
> > exception
> > "unexpected type, want: string got: binary" complaining that the
> > body
> > was binary.  I had to use something like this to convert my message
> > body
> > to a std::string:
> > 
> >    proton::binary __b = proton::get<proton::binary>(m.body());
> >    std::string _s = (std::string)__b;
> > 
> > If I send a string from Python, should it appear as binary in the
> > receiver?  What is the suggested way to write a receiver that can
> > handle
> > any arbitrary message that started as a string and may arrive in
> > some
> > other format, especially if the message broker or client is changed
> > at
> > some arbitrary time in the future?
> > 
> > I also observed similar issues receiving messages that had been
> > sent
> > into RabbitMQ by Kamailio's kazoo module[5], it is linked with the
> > librabbitmq client library.
> > 
> > Regards,
> > 
> > Daniel
> > 
> > 
> > 
> > 
> > 
> > 1. https://packages.qa.debian.org/q/qpid-proton.html
> > 2. https://packages.qa.debian.org/r/rabbitmq-server.html
> > 3.
> > https://qpid.apache.org/releases/qpid-proton-0.17.0/proton/python/e
> > xamples/simple_send.py.html
> > 4.
> > https://qpid.apache.org/releases/qpid-proton-0.17.0/proton/cpp/exam
> > ples/simple_recv.cpp.html
> > 5. http://www.kamailio.org/docs/modules/4.4.x/modules/kazoo.html
> > 
> > 
> > Error from RabbitMQ log:
> > 
> > =INFO REPORT====
> > accepting AMQP connection <0.891.0> (127.0.0.1:48410 ->
> > 127.0.0.1:5672)
> > 
> > =ERROR REPORT====
> > ** Generic server <0.897.0> terminating
> > ** Last message in was {'$gen_cast',
> >                            {frame,
> >                                {{'v1_0.transfer',
> >                                     {uint,0},
> >                                     {uint,0},
> >                                     {binary,<<"1">>},
> >                                     {uint,0},
> > 
> > false,false,undefined,undefined,undefined,
> >                                     undefined,undefined},
> > 
> > <<0,83,112,208,0,0,0,11,0,0,0,5,66,80,4,64,66,
> >                                   82,0,0,83,115,208,0,0,0,34,0,0,0,
> > 13,64,64,
> > 
> > 64,64,64,64,64,64,131,0,0,0,0,0,0,0,0,131,0,
> > 
> > 0,0,0,0,0,0,0,64,82,0,64,0,83,119,160,3,102,
> >                                   111,111>>},
> >                                <0.891.0>}}
> > ** When Server state ==
> > {state,<0.900.0>,<0.906.0>,unlimited,<0.891.0>,
> >                             <0.896.0>,
> >                             {[],[]},
> > 
> > {session,0,2147483647,2147483647,0,65535,65535,0,
> >                                 65535,65535,1,0,
> >                                 {0,nil},
> >                                 {0,nil}}}
> > ** Reason for termination ==
> > ** {function_clause,
> >        [{rabbit_amqp1_0_framing,fill_from_binary,
> >             [{'v1_0.amqp_value',undefined},<<"foo">>],
> >             [{file,"rabbitmq-
> > amqp1.0/src/rabbit_amqp1_0_framing.erl"},
> >              {line,56}]},
> >         {rabbit_amqp1_0_message,decode_section,1,
> >             [{file,"rabbitmq-
> > amqp1.0/src/rabbit_amqp1_0_message.erl"},
> >              {line,122}]},
> >         {rabbit_amqp1_0_message,assemble,4,
> >             [{file,"rabbitmq-
> > amqp1.0/src/rabbit_amqp1_0_message.erl"},
> >              {line,62}]},
> >         {rabbit_amqp1_0_message,assemble,1,
> >             [{file,"rabbitmq-
> > amqp1.0/src/rabbit_amqp1_0_message.erl"},
> >              {line,30}]},
> >         {rabbit_amqp1_0_incoming_link,transfer,4,
> >             [{file,"rabbitmq-
> > amqp1.0/src/rabbit_amqp1_0_incoming_link.erl"},
> >              {line,148}]},
> >         {rabbit_amqp1_0_session_process,handle_control,2,
> > 
> > [{file,"rabbitmq-amqp1.0/src/rabbit_amqp1_0_session_process.erl"},
> >              {line,214}]},
> >         {rabbit_amqp1_0_session_process,handle_cast,2,
> > 
> > [{file,"rabbitmq-amqp1.0/src/rabbit_amqp1_0_session_process.erl"},
> >              {line,134}]},
> >         {gen_server2,handle_msg,2,
> >             [{file,"src/gen_server2.erl"},{line,1022}]}]}
> > 
> > =ERROR REPORT====
> > closing AMQP connection <0.891.0> (127.0.0.1:48410 ->
> > 127.0.0.1:5672):
> > {handshake_error,running,<0.897.0>,
> >     {{symbol,"amqp:internal-error"},
> >      "Session error: ~p~n~p~n",
> >      [function_clause,
> >       [{rabbit_amqp1_0_framing,fill_from_binary,
> >            [{'v1_0.amqp_value',undefined},<<"foo">>],
> >            [{file,"rabbitmq-
> > amqp1.0/src/rabbit_amqp1_0_framing.erl"},
> >             {line,56}]},
> >        {rabbit_amqp1_0_message,decode_section,1,
> >            [{file,"rabbitmq-
> > amqp1.0/src/rabbit_amqp1_0_message.erl"},
> >             {line,122}]},
> >        {rabbit_amqp1_0_message,assemble,4,
> >            [{file,"rabbitmq-
> > amqp1.0/src/rabbit_amqp1_0_message.erl"},
> >             {line,62}]},
> >        {rabbit_amqp1_0_message,assemble,1,
> >            [{file,"rabbitmq-
> > amqp1.0/src/rabbit_amqp1_0_message.erl"},
> >             {line,30}]},
> >        {rabbit_amqp1_0_incoming_link,transfer,4,
> >            [{file,"rabbitmq-
> > amqp1.0/src/rabbit_amqp1_0_incoming_link.erl"},
> >             {line,148}]},
> >        {rabbit_amqp1_0_session_process,handle_control,2,
> > 
> > [{file,"rabbitmq-amqp1.0/src/rabbit_amqp1_0_session_process.erl"},
> >             {line,214}]},
> >        {rabbit_amqp1_0_session_process,handle_cast,2,
> > 
> > [{file,"rabbitmq-amqp1.0/src/rabbit_amqp1_0_session_process.erl"},
> >             {line,134}]},
> >        {gen_server2,handle_msg,2,
> >            [{file,"src/gen_server2.erl"},{line,1022}]}]]}}
> > 
> > 
> > 
> > -----------------------------------------------------------------
> > ----
> > To unsubscribe, e-mail: [email protected]
> > For additional commands, e-mail: [email protected]
> > 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to