Tuesday 15 September 2015

c# - HelloWorld example for sending an object over RabbitMQ via EasyNetQ between two different applications -



c# - HelloWorld example for sending an object over RabbitMQ via EasyNetQ between two different applications -

hi attempting send simple object through rabbitmq via easynetq. i'm having issues deserializing object on subscription side. able show me sample of how works. maintain in mind object beingness sent defined in it's own project , not shared among publisher , subscriber. here sample, , perhaps can tell me wrong it?

program a:

class programa { static void main(string[] args) { using (var bus = rabbithutch.createbus("host=localhost")) { console.writeline("press key send message"); console.readkey(); bus.publish(new messagea { text = "hello world" }); console.writeline("press key quit"); console.readkey(); } } public class messagea { public string text { get; set; } } }

program b:

class programb { static void main(string[] args) { using (var bus = rabbithutch.createbus("host=localhost")) { bus.subscribe<messageb>("", handleclusternodes); console.writeline("press key quit"); console.readkey(); } } private static void handleclusternodes(messageb obj) { console.writeline(obj.text); } [queue("testmessagesqueue", exchangename = "easynetqsample.programa+messagea:easynetqsample")] public class messageb { public string text { get; set; } } }

here error i'm receiving:

debug: handlebasicdeliver on consumer: f9ded52d-039c-411a-9b9f-5c8ee3301854, deliverytag: 1 debug: received routingkey: '' correlationid: 'ec41faea-a0c8-4ffd-8163-2cbf85d45fcd' consumertag: 'f9ded52d-039c-411a-9b9f-5c8ee3301854' deliverytag: 1 redelivered: false error: exception thrown subscription callback. exchange: 'easynetqsample.programa+messagea:easynetqsample' routing key: '' redelivered: 'false' message: {"text":"hello world"} basicproperties: contenttype=null, contentencoding=null, headers=[], deliverymode=2, priority=0, correlationid=ec41faea-a0c8-4ffd-8163-2cbf85d45fcd, replyto=null, expiration=null, messageid=null, timestamp=0, type=easynetqsample.programa+messagea:easynetqsample, userid=null, appid=null, clusterid=null exception: system.aggregateexception: 1 or more errors occurred. ---> easynetq.easynetqexception: cannot find type easynetqsample.programa+messagea:easynetqsample @ easynetq.typenameserializer.deserialize(string typename) @ easynetq.defaultmessageserializationstrategy.deserializemessage(messageproperties properties, byte[] body) @ easynetq.rabbitadvancedbus.<>c__displayclass19.<consume>b__18(byte[] body, messageproperties properties, messagereceivedinfo messagereceivedinfo) @ easynetq.rabbitadvancedbus.<>c__displayclass1e.<consume>b__1d(byte[] body, messageproperties properties, messagereceivedinfo receviedinfo) @ easynetq.consumer.handlerrunner.invokeusermessagehandler(consumerexecutioncontext context) --- end of inner exception stack trace --- ---> (inner exception #0) easynetq.easynetqexception: cannot find type easynetqsample.programa+messagea:easynetqsample @ easynetq.typenameserializer.deserialize(string typename) @ easynetq.defaultmessageserializationstrategy.deserializemessage(messageproperties properties, byte[] body) @ easynetq.rabbitadvancedbus.<>c__displayclass19.<consume>b__18(byte[] body, messageproperties properties, messagereceivedinfo messagereceivedinfo) @ easynetq.rabbitadvancedbus.<>c__displayclass1e.<consume>b__1d(byte[] body, messageproperties properties, messagereceivedinfo receviedinfo) @ easynetq.consumer.handlerrunner.invokeusermessagehandler(consumerexecutioncontext context)<---

what need able deserialize messagea?

as far know, default setting of easynetq requires type of serialized object consistent between applications. example, can send known .net type string:

bus.publish<string>("excellent.");

and happy on both projects.

you can utilize own message if set common library (dll). since specially mentioned reside in different projects, i'd suggest serialize , cast objects yourself.

easynetq uses interally newtonsoft json.net serialize objects this. can see, message has been serialized as:

message: {"text":"hello world"}

to yourself, still need add together reference json.net because easynetq hides reference using ilrepack.

this should work:

bus.publish<string>(jsonconvert.serializeobject(new messagea { text = "hello world" }));

and

bus.subscribe<string>("", handleclusternodes); private static void handleclusternodes(string obj) { var mymessage = (messageb)jsonconvert.deserializeobject<messageb>(obj); console.writeline(mymessage.text); }

but you'll lose attribute based routing , might want modify methods.

if want maintain using basic methods, can set topic this:

bus.publish<string>(jsonconvert.serializeobject(new messagea { text = "hello world" }), "topic.name"); bus.subscribe<string>("", handleclusternodes, new action<easynetq.fluentconfiguration.isubscriptionconfiguration>( o => o.withtopic("topic.name")));

but have complete control, need utilize advanced api;

var yourmessage = new message<string>(jsonconvert.serializeobject(new messagea { text = "hello world" })); bus.advanced.publish<string>(new exchange("yourexchangename"), "your.routing.key", false, false, yourmessage);

and on subscriber part:

iqueue yourqueue = bus.advanced.queuedeclare("anothertestmessagesqueue"); iexchange yourexchange = bus.advanced.exchangedeclare("yourexchangename", exchangetype.topic); bus.advanced.bind(yourexchange, yourqueue, "your.routing.key"); bus.advanced.consume<string>(yourqueue, (msg, info) => handleclusternodes(msg.body));

which same original rabbitmq c# client api.

detailed analysis:

the main problem exception:

easynetq.easynetqexception: cannot find type easynetqsample.programa+messagea:easynetqsample

this thrown easynetq because cannot find special class on endpoint.

if @ source code of typenameserializer.cs, see

var type = type.gettype(nameparts[0] + ", " + nameparts[1]); if (type == null) { throw new easynetqexception( "cannot find type {0}", typename); }

this tried find easynetqsample.programa.messagea type on second project, while knows easynetqsample.programb.messageb.

alternatively, can roll out own custom iserializer or set itypenameserializer default serializer haven't tried this.

c# rabbitmq easynetq

No comments:

Post a Comment