.net - RabbitMQ Pub/Sub: Closing the last consumer closes the publisher's channel/model. Why? -
i'm using .net rabbitmq pub/sub (publisher/subscriber) code. works fine until start closing consumers. consumers handle published data until close last consumer. after consumers, open new consumer, nothing happens. application opens, doesn't receive data publisher.
i checked publisher code , found out when last consumer closes, channel's isopen property becomes false. don't know if there setting keep channel open after consumer closed.
here publisher code: edit pasted wrong code.
and here consumer code:
public myconsumer { private readonly connectionfactory _factory; private readonly iconnection _connection; private readonly imodel _channel; private readonly timer _timer; private subscriptionconsumertype(string ipaddress, string exchangename, timespan tspullcycle) { //set connection this._factory = new connectionfactory(); this._factory.hostname = ipaddress; this._connection = this._factory.createconnection(); this._channel = this._connection.createmodel(); //set , bind exchange this._channel.exchangedeclare(exchangename, "fanout", false, true, new dictionary<string, object>()); string queuename = this._channel.queuedeclare().queuename; this._channel.queuebind(queuename, exchangename, ""); //start consuming queueingbasicconsumer consumer = new queueingbasicconsumer(this._channel); this._channel.basicconsume(queuename, true, consumer); //periodically check new messages publisher this._timer = new timer(new timercallback(this.timerstep), consumer, tspullcycle, tspullcycle); } public void dispose() { if (this._timer != null) this._timer.dispose(); if (this._channel != null) { this._channel.close(); this._channel.dispose(); } if (this._connection != null) { this._connection.close(); this._connection.dispose(); } } } right now, workaround have consumer window open somewhere. ideally though, want publisher run regardless of number of consumer windows open. thanks.
edit oops, pasted wrong producer code. here that:
private subscriptionbroadcasttype(string ipaddress, string exchangename) { this._factory = new connectionfactory(); this._factory.hostname = ipaddress; this._connection = this._factory.createconnection(); this._channel = this._connection.createmodel(); this._exchangename = exchangename; this._channel.exchangedeclare(exchangename, subscriptionbroadcasttype.broadcast, subscriptionbroadcasttype.durable, subscriptionbroadcasttype.auto_delete, new dictionary<string, object>()); } public void broadcastmessage(string message) { lock (this._syncroot) //protect _channel { if (this._channel.isopen) this._channel.basicpublish(this._exchangename, "", null, system.text.encoding.utf8.getbytes(message)); } }
i think may have fundamentally wrong here. please check have published correct code. read have producer creating specific named queue , publishing directly queue. have consumer creating specific named exchange , creating new queue dynamically named , binding exchange. reading queue, can't queue published to.
i fix code first add create exchange in publisher code specific name have access in consumer code. line appear in producer thread instead of queue declare line:
this._channel.exchangedeclare(exchangename, "fanout", false, true, new dictionary<string, object>()); then need publish exchange instead of line publishes queue change to:
this._channel.basicpublish(exchangename, "", this._basicproperties, system.text.encoding.utf8.getbytes(message)); your consumer should set fine receive these messages queue is. see if helps problem.
Comments
Post a Comment