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]
