使用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. VHDL的参数写在一个vhd文件里

    1 参数文件top_pkg.vhd

  2. Android广播

    Android中的广播主要分为两类,标准广播和有序广播   标准广播: 一种完全异步执行的广播,在广播发出之后,所有的广播接收器几乎都会在同一时刻接收到这条广播消息,因此没有任何的先后顺序 这种广播的 ...

  3. C——malloc & free(转载自bccn C语言论坛)

    原帖及讨论:http://bbs.bccn.net/thread-82212-1-1.html 原文链接:http://www.bccn.net/Article/kfyy/cyy/jszl/20060 ...

  4. supervisor centos安装

    一.安装配置supervisor 1.安装python自动化工具    #yum install python-setuptools 2.#easy_install supervisor安装super ...

  5. 数据表格datagrid内容整理

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...

  6. JSP页面中的精确到秒的时间控件

    技术:Struts1+jsp+MSql 需求:ncmgt网络监控系统中显示用户的操作日志,并且根据操作时间查询用户的详细操作记录.时间精确到秒 大致效果如下.上图! 大家可以清晰的看到.红色画线部分就 ...

  7. ZOJ 3817Chinese Knot(The 2014 ACM-ICPC Asia Mudanjiang Regional First Round)

    思路: 将4个串每个串都反向这样得到新的四个串一共8个串,对于母串每个位置检测这个串能不能放进去,hs或者后缀数组都可以.然后dp[i][j]  (0<i<len  0<=j< ...

  8. Ubuntu上安装MySql过程,以及遇到的一些问题

    今天在Ubuntu服务器上安装MySql的时候遇到了一些问题,记录下来,以防以后忘记. 安装环境:Ubuntu14.04 安装命令: //安装Mysal服务端//会提示输入root密码 sudo ap ...

  9. 爬虫:selenium + phantomjs 解决js抓取问题(一)

    selenium模块主要用来做测试,模拟键盘.鼠标来操作浏览器. phantomjs 就像一个无界面的浏览器一样. 两个结合能很好的解决js抓取的问题. 测试代码: #coding=utf-8 fro ...

  10. Spring init-method和destroy-method 的使用

    Spring init-method和destroy-method 的使用 Spring 为了满足开发者在执行某方法之前或者在结束某个任务之前需要操作的一些业务,则提供了init-method和des ...