使用RabbitMQ时,连接rabbit-server一直连接失败,代码没有任何错误提示。但是通过rabbitmqctl始终查询不到连接以及创建的queue等信息。

官方的文件demo里面也没有TcpConnection相关例子,只在github上有些简单说明。

然而网上几乎所有人都依然还是在使用Connection,几乎没有使用TcpConnection的例子。最后还是放弃了网络求助,老老实实看源码定位了。

使用tcpdump确认,代码这边的TcpConnection确实是已经向rabbit-server发出了连接请求。

开始观察发现三次握手是已经建立了连接的,但是几秒后,rabbit-server主动发送返回了一个RST包。这非常诧异,查看rabbit-server日志看到,产生了一次handshake_timeout错误。

现在可以确认,不是鉴权产生的问题,而是在连接时就已经失败了,在完成连接到RST包收到刚好过了10s时间。在官方文档查阅到,rabbit-server的心跳也刚好是10s。

后来还是确定问题点是在代码上,但是代码只有短短几行从github上copy下来的,怎么会出错呢。

最后在日志打印上发现monitor函数执行了两次,这个小小的信息感觉看到了问题的原因,查看TcpConnection源码monitor被调用的地方。

 public:
/**
* Constructor
* @param connection Parent TCP connection object
* @param socket The socket filedescriptor
* @param buffer The buffer that was already built
* @param handler User-supplied handler object
*/
TcpConnected(TcpConnection *connection, int socket, TcpOutBuffer &&buffer, TcpHandler *handler) :
TcpState(connection, handler),
_socket(socket),
_out(std::move(buffer)),
_in()
{
// if there is already an output buffer, we have to send out that first
if (_out) _out.sendto(_socket); // tell the handler to monitor the socket, if there is an out
_handler->monitor(_connection, _socket, _out ? readable | writable : readable);
} /**
* Destructor
*/
virtual ~TcpConnected() noexcept
{
// we no longer have to monitor the socket
_handler->monitor(_connection, _socket, ); // close the socket
close(_socket);
}

在构造和析构中各调用了一次,而且内部使用connection可能是为了提高效率进行了线程操作,也就是说实际的connection是在多线程中完成的。

最后尝试修改代码,使用指针进行操作,因为代码并不是github上的单个函数文件,而是多处引用,最后问题解决。成功使用TcpConnection连接上了rabbit-server。

附上简单代码:

 int Broker::init(std::string host,int port, std::string username, std::string userpasswd, int svrid)
{
// create an instance of your own tcp handler
_handle = new DSBrokerMessageHandle(); // address of the server
AMQP::Address address(host, port,AMQP::Login(username,userpasswd),"/"); // create a AMQP connection object
_connection = new AMQP::TcpConnection(_handle, address);

// and create a channel
_channel = new AMQP::TcpChannel(&connection); auto receiveMessageCallback = [=](const AMQP::Message &message,
uint64_t deliveryTag,
bool redelivered)
{
//_channel->ack(deliveryTag);
}; AMQP::QueueCallback callback =
[=](const std::string &name, int msgcount, int consumercount)
{
_channel->bindQueue("service", name, name);
_channel->bindQueue("service", name, "monitor");
_channel->bindQueue("service", name, "heartbeat"); _channel->consume(name, AMQP::noack).onReceived(receiveMessageCallback);
}; AMQP::SuccessCallback success = [svrid, this, callback]()
{
char que[] = { '\0' };
ACE_OS::itoa(svrid, que, );
std::string quename(que);
_channel->declareQueue(quename, AMQP::durable).onSuccess(callback);
}; // use the channel object to call the AMQP method you like
_channel->declareExchange("service", AMQP::fanout).onSuccess(success); return ;
}

RabbitMQ - TcpConnection析构引发的一次handshake_timeout的更多相关文章

  1. rabbitmq在ios中实战采坑

    1. rabbitmq在ios中实战采坑 1.1. 问题 ios使用rabbitmq连接,没过多久就断开,并报错.且用android做相同的步骤并不会报错,错误如下 Received connecti ...

  2. 简述C#中IO的应用 RabbitMQ安装笔记 一次线上问题引发的对于C#中相等判断的思考 ef和mysql使用(一) ASP.NET/MVC/Core的HTTP请求流程

    简述C#中IO的应用   在.NET Framework 中. System.IO 命名空间主要包含基于文件(和基于内存)的输入输出(I/O)服务的相关基础类库.和其他命名空间一样. System.I ...

  3. RabbitMQ入门教程——安装及配置

    RabbitMQ是一个消息代理,一个消息系统的媒介,提供了一个通用的消息发送及接收平台,并且能够保障消息传输过程中的安全.使用erlang语言开发,开源,在易用性.扩展性.高可用性等方面表现不俗 技术 ...

  4. rabbitmq.config配置参数详解

    rabbitmq.config详细配置参数 详细使用方法请点击:http://www.cnblogs.com/wyt007/p/9073316.html Key Documentation tcp_l ...

  5. RabbitMQ-官方指南-RabbitMQ配置

    原文:http://www.rabbitmq.com/configure.html RabbitMQ 提供了三种方式来定制服务器: 环境变量 定义端口,文件位置和名称(接受shell输入,或者在环境配 ...

  6. (转)rabbitmq.config详细配置参数

    rabbitmq.config详细配置参数 Key Documentation tcp_listeners 用于监听 AMQP连接的端口列表(无SSL). 可以包含整数 (即"监听所有接口& ...

  7. rabbitmq.config详细配置参数

    原文:rabbitmq.config详细配置参数 rabbitmq.config详细配置参数 详细使用方法请点击:http://blog.csdn.net/Super_RD/article/detai ...

  8. .NET文件并发与RabbitMQ(初探RabbitMQ)

    本文版权归博客园和作者吴双本人共同所有.欢迎转载,转载和爬虫请注明原文地址:http://www.cnblogs.com/tdws/p/5860668.html 想必MQ这两个字母对于各位前辈们和老司 ...

  9. Thread.Sleep引发ThreadAbortException异常

    短信平台记录日志模块,是通过异步方式来记录的,即日志工具类里初始化一个Queue对象,公共的写日志方法的处理逻辑是把日志消息放到Queue里.构造器里设定一个死循环,不停的读队,然后把日志消息持久化到 ...

随机推荐

  1. Error 403--Forbidden

    转自他人:From RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1:10.4.4 403 ForbiddenThe server understood ...

  2. 使用Kettle抽取数据时,出现中文乱码问题解决方案

    使用Kettle在不同的数据库抽取数据时,有时会出现中文乱码问题:其解决方案如下: 1.查看数据库的字符集是否是UTF-8(最常用的字符集) 2.如果数据库设置正确仍然存在中文乱码,则可能是因为有的客 ...

  3. lock

    #ifndef lock_h #define lock_h #include <stdint.h> #include <string.h> #include "myd ...

  4. C#中REF和OUT的区别

    在C# 中,既可以通过值也可以通过引用传递参数.通过引用传递参数允许函数成员更改参数的值,并保持该更改.若要通过引用传递参数, 可使用ref或out关键字.ref和out这两个关键字都能够提供相似的功 ...

  5. 误设PATH导致命令失效的处理

    今天配置Linux下的Java环境时,把PATH设为了export PATH=${JAVA_HOME}/bin,然后执行了source ~/.bash_profile命令,导致了几乎所有的Linux命 ...

  6. Eclipse JUnit 生成报告

    http://blog.sina.com.cn/s/blog_8af106960102v6qh.html 对Eclipse的工程写单元测试: 第一步: 1. 一个工程有多个测试类,将测试类放到一个测试 ...

  7. JavaScript拼图游戏

    今天是2016年最后一天上班了.最近几天都比较休闲,有时间空闲下来写写文档之类的. 2016过得真是快.感觉没做什么就过去了.想到之前想坚持每个月写一写博客都没坚持到.希望2017年可以吧. 无聊之余 ...

  8. python 版 mldivide matlab 反除(左除)《数学建模算法与程序》Python笔记

    今天在阅读数学建模的时候看到了差分那章 其中有一个用matlab求线性的代码,这里我贴出来 这里我送上 Python代码 In [39]: import numpy as np ...: from s ...

  9. Xcode真机调试报错(证书的签发者无效)

    Xcode真机调试时报错: dyld: Library not loaded: @rpath/libswiftAVFoundation.dylib Referenced from: /var/mobi ...

  10. ArrayList和Vector的区别

    3.ArrayList和Vector的区别 答: 这两个类都实现了List接口(List接口继承了Collection接口),他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,相当于一种 ...