EasyNetQ Consume Binary Message - rabbitmq

I use the following code to publish a raw message to the queue:
using (var bus = RabbitHutch.CreateBus("host=myserver;virtualHost=myhost;username=xxx;password=yyy").Advanced)
{
var queue = bus.QueueDeclare("MyQueue");
var exchange = bus.ExchangeDeclare("MyExchange", ExchangeType.Topic);
var binding = bus.Bind(exchange, queue, "");
var properties = new MessageProperties();
var body = System.Text.Encoding.UTF8.GetBytes("This is the body of the message");
bus.Publish(exchange, "", false, false, properties, body);
}
The message got delivered to the queue and I see one message in the queue from RabbitMQ's console. However, when I try to consume it with the following code I'm not getting anything back:
bus.Consume(queue, (body, properties, info) => Task.Factory.StartNew(() =>
{
var message = Encoding.UTF8.GetString(body);
Console.Out.WriteLine("Got message: '{0}'", message);
}));
I can see the message is delivered from Rabbit's console but nothing gets printed out and the message is still in the queue. What am I missing?

Related

I have created a pub/sub model using #nestjs-plus/rabbitmq library but not being able to send acknowledgement from subscriber to publisher

I have used #RabbitSubscribe() decorator for subscription and AmqpConnection.publish() for publisher and Pub/Sub is working properly. But I want acknowledgement back from subscriber to publisher when message will be delivered.
I expect the publisher should receive acknowledgement from subscriber.
To get an answer, you need to use RPC Handlers.
Send message:
const requestOptions: RequestOptions = {
payload: {foo: 'bar'},
exchange: 'exchange1',
routingKey: 'rpc-route'
};
const result = await this.amqpConnection.request(requestOptions);
Message handling and response:
#RabbitRPC({
exchange: 'exchange1',
routingKey: 'rpc-route',
queue: 'rpc-queue'
})
public async rpcHandler(msg: {}) {
return {
response: 42
};
}

Rabbitmq doesn't persistent a message in exchange if there is no subscriber?

I have the following publisher and subscriber:
// publisher.js
var amqp = require('amqplib/callback_api');
amqp.connect('amqp://localhost', function(err, conn) {
conn.createChannel(function(err, ch) {
var ex = 'logs';
var msg = process.argv.slice(2).join(' ') || 'Hello World!';
ch.assertExchange(ex, 'fanout', {durable: true});
ch.publish(ex, '', new Buffer(msg));
console.log(" [x] Sent %s", msg);
});
setTimeout(function() { conn.close(); process.exit(0) }, 500);
});
//subscriber.js
var amqp = require('amqplib/callback_api');
amqp.connect('amqp://localhost', function(err, conn) {
conn.createChannel(function(err, ch) {
var ex = 'logs';
ch.assertExchange(ex, 'fanout', {durable: true});
ch.assertQueue('', {exclusive: true}, function(err, q) {
console.log(" [*] Waiting for messages in %s. To exit press CTRL+C", q.queue);
ch.bindQueue(q.queue, ex, '');
ch.consume(q.queue, function(msg) {
if(msg.content) {
console.log(" [x] %s", msg.content.toString());
}
}, {noAck: true});
});
});
});
If I run the publisher.js to publish two messages, and then run the subscriber.js, I would expect the subscriber to print two messages that I published in the past, but actually subscriber doesn't receive any messages.
How to let RabbitMQ persist the published messages that allow any subscriber to consume from the beginning or wherever they consumed last time?
If RabbitMQ can't route a message to a queue, the message is dropped.
Since you run your publisher code prior to your subscriber code, there is no queue bound to your exchange and, thus, nowhere to route the message.
You need to either run your subscriber code before your publisher, or you have to have your publisher or some other process create and bind a named queue to your exchange. Then, your subscriber will use that queue.
NOTE: the RabbitMQ team monitors the rabbitmq-users mailing list and only sometimes answers questions on StackOverflow.

Dart and RabbitMQ bind exchange

I use STOMP package, and I wrote a test:
test('can subscribe and send events to mq server', () async {
StompClient client2 = await serverClient.connect(mqIp,
port: mqPort, login: login, passcode: password);
client2.sendJson('Domain changed', {'a':'b'});
client2.disconnect();
StreamController controller = new StreamController();
Stream<String> stream = controller.stream.asBroadcastStream();
StompClient client1 = await serverClient.connect(mqIp,
port: mqPort, login: login, passcode: password);
client1.subscribeString("Entity changed", 'Domain changed',
(Map<String, String> headers, String message) {
controller.add(message);
}, ack: AUTO);
await for (String message in stream) {
String expectedEntity =
'{\"a\":\"b\"}';
expect(message, equals(expectedEntity));
break;
}
client1.unsubscribe("Entity changed");
client1.disconnect();
}, timeout: new Timeout(new Duration(seconds: 6)));
When I run pub run test I get Test timed out.
In RabbitMQ Managment in bindings section I get: (Default exchange binding) and zero in total messages:
Is it possible to send and recive messages in one channel?
If I use client1.subscribeString(ack: CLIENT,...) in RabbitMQ Managment I get one message "In memory" but test still Test timed out and I can't get message from mq.
Maybe I must set up amq.fanout exchange, but how I can do this?
Best choice for use RabbitMq with dart: mqtt package

MassTransit consume non MassTransit message

I have a console app that is publishing messages to a RabbitMQ exchange. Is it possible for a subscriber that is built with MassTransit to consume this message?
This is the publisher code:
public virtual void Send(LogEntryMessage message)
{
using (var connection = _factory.CreateConnection())
using (var channel = connection.CreateModel())
{
var props = channel.CreateBasicProperties();
props.CorrelationId = Guid.NewGuid().ToString();
var body = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(message));
channel.BasicPublish(exchange: _endpointConfiguration.Exchange, routingKey: _endpointConfiguration.RoutingKey, basicProperties: null,
body: body);
}
}
This is the subscriber code:
IBusControl ConfigureBus()
{
return Bus.Factory.CreateUsingRabbitMq(cfg =>
{
var host = cfg.Host(new Uri("rabbitmq://localhost"), h =>
{
h.Username(username);
h.Password(password);
});
cfg.ReceiveEndpoint(host, "LogEntryQueue", e =>
{
e.Handler<LogEntryMessage>(context =>
Console.Out.WriteLineAsync($"Value was entered: {context.Message.MessageBody}"));
});
});
}
This is the consumer code:
public class LogEntryMessageProcessor : IConsumer<LogEntryMessage>
{
public Task Consume(ConsumeContext<LogEntryMessage> context)
{
Console.Out.WriteLineAsync($"Value was entered:
{context.Message.Message.MessageBody}");
return Task.FromResult(0);
}
}
I hope you can get the answer in the Interoperability section, in particular look at the example message.
Basically, you need to construct a JSON object according to some simple rules.
Example message looks like this:
{
"destinationAddress": "rabbitmq://localhost/input_queue",
"headers": {},
"message": {
"value": "Some Value",
"customerId": 27
},
"messageType": [
"urn:message:MassTransit.Tests:ValueMessage"
]
}
You can easily check how more complex messages look like by creating both publisher and consumer, run the program in order to create bindings, then stop the consumer and publish some messages. They will be in the subscriber queue so you can easily read them using the management plugin.
For MassTransit to process a message that is published by non-MassTransit client,
the message has to contain the metadata required by MassTransit as described in the Interoperability page.
The consumer of the message has to process the payload of the message.
In the code below, the payload is LogEntryPayload:
public class LogEntryMessageProcessor : IConsumer<LogEntryPayload>
{
public Task Consume(ConsumeContext<LogEntryPayload> context)
{
//var payload = context.GetPayload<LogEntryPayload>();
Console.Out.WriteLineAsync($"Value was entered: {context.Message.Id} - {context.Message.MessageBody}");
return Task.FromResult(0);
}
}

Consume WCF service in Titanium

I have written a code to consume the WCF service in my Titanium Project.
Alloy.Globals.wcfservice=function callservice()
{
//fetching data from server.
var xhr = Titanium.Network.createHTTPClient();
xhr.setTimeout(1200);
console.log(xhr.status);
console.log(xhr.statusText);
xhr.onerror = function(e) /* on error in getting data from server */
{
//check response status and act aaccordingly.
if (xhr.status != 200) {
alert("The service is currently unavailable. Please Try Again Later.");
return;
}
};
//on getting response from server.
xhr.onload = function()
{
alert(this.responseText);
var response = XML.parse(this.responseText);
};
//set the url for the service to the get student courses
var request_url = getWebserviceURL() + "GetAvailableAppointmentFromWCF";
console.log(request_url);
xhr.open("POST", request_url);
xhr.send();
};
But I always receive status as 0, "the service is currently unavailable. Please Try Again Later" . What wrong am I doing in this code?