RabbitMQ connect to cloudAMQP : An existing connection was forcibly closed by the remote host - rabbitmq

I am having a issue with connect to CloudAMQP. That is the code and error
copy from the cloudamqp guideline.
void Start()
{
// I replaced the url that I got from cloudamqp
private static readonly string _url = "amqp://guest:guest#localhost/%2f";
// Create a ConnectionFactory and set the Uri to the CloudAMQP url
// the connectionfactory is stateless and can safetly be a static resource in your app
var factory = new ConnectionFactory
{
uri = new Uri(url)
};
// create a connection and open a channel, dispose them when done
using var connection = factory.CreateConnection();
using var channel = connection.CreateModel();
// ensure that the queue exists before we publish to it
var queueName = "queue1";
bool durable = false;
bool exclusive = false;
bool autoDelete = true;
channel.QueueDeclare(queueName, durable, exclusive, autoDelete, null);
// read message from input
var message = "hello";
// the data put on the queue must be a byte array
var data = Encoding.UTF8.GetBytes(message);
// publish to the "default exchange", with the queue name as the routing key
var exchangeName = "";
var routingKey = queueName;
channel.BasicPublish(exchangeName, routingKey, null, data);
}
the issues is
SocketException: An existing connection was forcibly closed by the remote host.
System.Net.Sockets.Socket.Receive (System.Byte[] buffer, System.Int32 offset, System.Int32 size, System.Net.Sockets.SocketFlags socketFlags) (at :0)
System.Net.Sockets.NetworkStream.Read (System.Byte[] buffer, System.Int32 offset, System.Int32 size) (at :0)
Rethrow as IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
does any one know how to slove it?

Related

RabbitMQ queue declare never ends

I'm just trying to make a simple test for RabbitMQ, and I have Erlang installed as well as RabbitMQ running.
My receiver:
private final static String QUEUE_NAME = "hello";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
Consumer consumer = new DefaultConsumer(channel) {
#Override
public void handleDelivery(String consumerTag, Envelope envelope,
BasicProperties properties, byte[] body) throws IOException
{
// TODO Auto-generated method stub
String message = new String(body, "UTF-8");
System.out.println(" [x] Received '" + message + "'");
}
};
channel.basicConsume(QUEUE_NAME, true, consumer);
}
It never prints out the first sysout, because it gets stuck declaring the queue on "channel.queueDeclare" line.
Rabbit log says it is accepting AMQP connection and user guest gets authenticated and granted access to vhost.
Any help would be appreciated.
I just copied/pasted your code with no problems...
[*] Waiting for messages. To exit press CTRL+C
[x] Received 'foo'
I suggest you enable the management plugin and explore the admin UI.
Why did you add the spring-amqp spring-rabbitmq tags since this question has nothing to do with Spring and you are using the native client directly?

RabbitMQ .NET Client and connection timeouts

I'm trying to test the AutomaticRecoveryEnabled property of the RabbitMQ ConnectionFactory. I'm connecting to a RabbitMQ instance on a local VM and on the client I'm publishing messages in a loop. The problem is if I intentionally break the connection, the client just waits forever and doesn't time out. How do I set the time out value? RequestedConnectionTimeout doesn't appear to have any effect.
I'm using the RabbitMQ client 3.5.4
Rudimentary publish loop:
// Client is a wrapper around the RabbitMQ client
for (var i = 0; i < 1000; ++i)
{
// Publish sequentially numbered messages
client.Publish("routingkey", GetContent(i)));
Thread.Sleep(100);
}
The Publish method inside the wrapper:
public bool Publish(string routingKey, byte[] body)
{
try
{
using (var channel = _connection.CreateModel())
{
var basicProps = new BasicProperties
{
Persistent = true,
};
channel.ExchangeDeclare(_exchange, _exchangeType);
channel.BasicPublish(_exchange, routingKey, basicProps, body);
return true;
}
}
catch (Exception e)
{
_logger.Log(e);
}
return false;
}
The connection and connection factory:
_connectionFactory = new ConnectionFactory
{
UserName = _userName,
Password = _password,
HostName = _hostName,
Port = _port,
Protocol = Protocols.DefaultProtocol,
VirtualHost = _virtualHost,
// Doesn't seem to have any effect on broken connections
RequestedConnectionTimeout = 2000,
// The behaviour appears to be the same with or without these included
// AutomaticRecoveryEnabled = true,
// NetworkRecoveryInterval = TimeSpan.FromSeconds(10),
};
_connection = _connectionFactory.CreateConnection();
It appears this is a bug in version 3.5.4. Version 3.6.3 does not wait indefinitely.

Rabbitmq - how to listen to messages on an exchange

I have a program in Java that sends messages to RabbitMQ. All I know is the exchange name. No queues, bindings, and so on.
My question is this: how can I see if the program sends these successfully, knowing only the exchange name?
Thanks.
Regards,
Serban
You can enable publisher confirmation with RabbitMQ. It's like having a send-transaction, where RabbitMQ will tell you whether or not the message was sent successfully.
Assume that we have RabbitMQ Exchange we need to create an queue to push the message to the exchange and consume it from the queue as following
private static final String EXCHANGE_NAME = "2022";
private static final String QUEUE_NAME = "2022";
private final static boolean durable = true;
// now we need to create a connection to rabbitmq server //
ConnectionFactory factory = new ConnectionFactory();
factory.setUsername("guest");
factory.setPassword("guest");
factory.setVirtualHost("/");
factory.setHost("127.0.0.1");
factory.setPort(5672);
Connection conn = factory.newConnection();
// create rabbitmq connection chaneel
Channel channel = conn.createChannel();
//Declare Exchange //
channel.exchangeDeclare(EXCHANGE_NAME, "topic", true);
// push message to rabbitmq exchange
channel.basicPublish(EXCHANGE_NAME, "routingkey", null, yourmessage.getBytes());
the above work as producer now we need to create queue consumer
private static final String EXCHANGE_NAME = "2022";
private static final String QUEUE_NAME = "2022";
private final static boolean durable = true;
// now we need to create a connection to rabbitmq server //
ConnectionFactory factory = new ConnectionFactory();
factory.setUsername("guest");
factory.setPassword("guest");
factory.setVirtualHost("/");
factory.setHost("127.0.0.1");
factory.setPort(5672);
Connection conn = factory.newConnection();
// create rabbitmq connection chaneel
Channel channel = conn.createChannel();
channel.exchangeDeclare(EXCHANGE_NAME, "topic", true);
//Queue Declare //
channel.queueDeclare(QUEUE_NAME, true, false, false, null);
//Queue bind //
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "routingkey");
// Queue Consume //
QueueingConsumer consumer = new QueueingConsumer(channel);
while (true)
{
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println(" [x] Received '" + message + "'");
}
Please look here: https://www.rabbitmq.com/tutorials/tutorial-three-java.html
String queueName = channel.queueDeclare().getQueue();
channel.queueBind(queueName, "EXCHANGE_NAME", "");
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
Consumer consumer = new DefaultConsumer(channel) {
#Override
public void handleDelivery(String consumerTag,
Envelope envelope,
AMQP.BasicProperties properties,
byte[] body) throws IOException
{
String message = new String(body, "UTF-8");
System.out.println(" [x] Received '" + message + "'");
}
};
channel.basicConsume(queueName, true, consumer);
In a few words, you have to:
create a queue, in this case anonymous queue
bind the queue to your exchange
It is important to know what kind of the exchange you have since the binding can change, between fanout or topic or direct
In this example is fanout

what host to set for RabbitMQ send test

So I am having trouble understanding how to use rabbitmq. I have the following Send.java class I am using RabbitMQ to send a message:
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Channel;
public class Send {
private final static String QUEUE_NAME = "hello";
public static void main(String[] argv) throws java.io.IOException {
// create a connection to the server
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("WHAT DO I PUT HERE"); // <==========================What do I put here??
Connection connection = factory.newConnection();
// next we create a channel, which is where most of the API
// for getting things done resides
Channel channel = connection.createChannel();
// to send we must declare a queue for us to send to; then
// we can publish a message to the queue:
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
String message = "Hello World!";
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
System.out.println(" [x] Sent '" + message + "'");
channel.close();
connection.close();
}
}
I don't really understand what I can set the host as to make this run as a Java application. Can someone explain? Thanks!
It's really self-explanatory... This method sets the default host to use for connection.
If you're using RabbitMQ on your local machine you can set it like this:
factory.setHost("localhost");
Or alternatively:
factory.setHost("127.0.0.1");

WCF client can't connect to non WCF named pipe server

I have a WCF named pipe server, a non WCF named pipe server, a WCF named pipe client and a non wcf named pipe client.
The non WCF client can connect to both servers. The WCF client can only connect to the WCF server. When I try to connect it to the non WCF client I get this exception.
Unhandled Exception: System.ServiceModel.EndpointNotFoundException: There was no endpoint
listening at net.pipe://localhost/PipePlusFive that could accept the message. This is
often caused by an incorrect address or SOAP action. See InnerException,
if present, for more details. ---> System.IO.PipeException: The pipe endpoint
'net.pipe://localhost/PipePlusFive' could not be found on your local machine.
--- End of inner exception stack trace ---
According this the actual name of a pipe is a guid stored in a memory mapped file. I assume this is handled automagically for the WCF client and server. for the non WCF server I create the memory mapped file, write a guid to it, then create the pipe using that guid for the name. In the non WCF client I open the memory mapped file, read the pipe name from it, and then use that name to connect to the pipe. Then fact I can connect to both servers using the non WCF client without changing anything leads me to believe that I'm implementing this part correctly on both the server and the client.
Also when I start the non WCF server then start the WCF server the second crashes stating that it cannot listen on that pipe name because another endpoint is already listening.
I'm wondering why the WCF client can't find the non WCF server when the non WCF client can find both? is there something else WCF uses to find an end point besides what is described in the blog I linked to?
UPDATE:
Here is the code I'm using for the WCF client:
class Program
{
static void Main(string[] args)
{
ChannelFactory<IPlusFive> pipeFactory =
new ChannelFactory<IPlusFive>(new NetNamedPipeBinding(NetNamedPipeSecurityMode.None), new EndpointAddress("net.pipe://localhost/PipePlusFive"));
IPlusFive pipeProxy = pipeFactory.CreateChannel();
while (true)
{
string str = Console.ReadLine();
if (str.Equals("q"))
{ return; }
Console.WriteLine(pipeProxy.PlusFive(Int32.Parse(str)));
}
}
}
Here is the code I'm using for the WCF server:
class Program
{
static void Main(string[] args)
{
var inst = new PlusFiver();
using (ServiceHost host = new ServiceHost(inst,
new Uri[] { new Uri("net.pipe://localhost") }))
{
host.AddServiceEndpoint(typeof(IPlusFive), new NetNamedPipeBinding(NetNamedPipeSecurityMode.None), "PipePlusFive");
host.Open();
Console.WriteLine("Service is Available. Press enter to exit.");
Console.ReadLine();
host.Close();
}
}
}
Here is the code that I'm using for the non WCF server:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Creating Memory Mapped file...");
string fileName = GenerateFileMapName(String.Empty);
Guid pipeName = Guid.NewGuid();
Console.WriteLine(" writing pipe name: " + pipeName.ToString("D"));
MemoryMappedFile mmf = null;
var messageList = new List<byte>();
try
{
mmf = WritePipeName(fileName, pipeName);
Console.WriteLine("Creating Named Pipe");
Console.WriteLine("Pipe Name: " + GetPipeNameFromMappedFile(fileName, mmf));
using (var pipe = new NamedPipeServerStream(pipeName.ToString("D"), PipeDirection.InOut))
{
Console.WriteLine("pipe created");
Console.WriteLine("Waiting for connection");
pipe.WaitForConnection();
Console.WriteLine("Received Connection");
Console.WriteLine("Waiting to receive data");
var bytes = new byte[7];
pipe.Read(bytes, 0, 7);
messageList.AddRange(bytes);
bytes = new byte[messageList[6]];
pipe.Read(bytes, 0, messageList[6]);
messageList.AddRange(bytes);
bytes = new byte[2];
pipe.Read(bytes, 0, 2);
messageList.AddRange(bytes);
messageList.Add((byte)pipe.ReadByte());
pipe.WriteByte(0x0b);
WriteList(messageList);
Console.WriteLine("Finished reading from pipe");
PrintBytes(bytes);
Console.WriteLine("Closing Connection");
pipe.Disconnect();
Console.WriteLine("Pipe disconnected");
//Console.Read();
}
}
finally
{
mmf.Dispose();
}
}
private static void WriteList(List<byte> messageList)
{
foreach (var b in messageList)
{
Console.Write(b.ToString("x2") + " ");
}
Console.WriteLine();
}
private static void PrintBytes(byte[] bytes)
{
foreach (var b in bytes)
{
Console.Write(b.ToString("x2") + " ");
}
Console.WriteLine();
}
private static string GenerateFileMapName(string uri)
{
return "net.pipe:EbmV0LnBpcGU6Ly8rLw==";
}
private static MemoryMappedFile WritePipeName(string fileName, Guid pipeName)
{
var mmf = MemoryMappedFile.CreateNew(fileName, pipeName.ToByteArray().Count());
Console.WriteLine("Memory Mapped File Created.");
using (var accessor = mmf.CreateViewAccessor(4, 45))
{
Console.WriteLine("Writing pipe name to file");
accessor.Write(0, ref pipeName);
Console.WriteLine("Finished writing pipe name to file");
}
return mmf;
}
private static string GetPipeNameFromMappedFile(string filename, MemoryMappedFile mmf)
{
Guid pipeName;
using (var accessor = mmf.CreateViewAccessor(4, 45))
{
accessor.Read<Guid>(0, out pipeName);
}
return pipeName.ToString("D");
}
}
WCF endpoint netNamedPipeBinding is designed to connect to WCF named pipe server. When WCF client established connection using this type of binding it makes the same preparations as specified in the article you mentioned. That post will clarify the rest details.