RabbitMQ - TcpConnection析构引发的一次handshake_timeout
使用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的更多相关文章
- rabbitmq在ios中实战采坑
1. rabbitmq在ios中实战采坑 1.1. 问题 ios使用rabbitmq连接,没过多久就断开,并报错.且用android做相同的步骤并不会报错,错误如下 Received connecti ...
- 简述C#中IO的应用 RabbitMQ安装笔记 一次线上问题引发的对于C#中相等判断的思考 ef和mysql使用(一) ASP.NET/MVC/Core的HTTP请求流程
简述C#中IO的应用 在.NET Framework 中. System.IO 命名空间主要包含基于文件(和基于内存)的输入输出(I/O)服务的相关基础类库.和其他命名空间一样. System.I ...
- RabbitMQ入门教程——安装及配置
RabbitMQ是一个消息代理,一个消息系统的媒介,提供了一个通用的消息发送及接收平台,并且能够保障消息传输过程中的安全.使用erlang语言开发,开源,在易用性.扩展性.高可用性等方面表现不俗 技术 ...
- rabbitmq.config配置参数详解
rabbitmq.config详细配置参数 详细使用方法请点击:http://www.cnblogs.com/wyt007/p/9073316.html Key Documentation tcp_l ...
- RabbitMQ-官方指南-RabbitMQ配置
原文:http://www.rabbitmq.com/configure.html RabbitMQ 提供了三种方式来定制服务器: 环境变量 定义端口,文件位置和名称(接受shell输入,或者在环境配 ...
- (转)rabbitmq.config详细配置参数
rabbitmq.config详细配置参数 Key Documentation tcp_listeners 用于监听 AMQP连接的端口列表(无SSL). 可以包含整数 (即"监听所有接口& ...
- rabbitmq.config详细配置参数
原文:rabbitmq.config详细配置参数 rabbitmq.config详细配置参数 详细使用方法请点击:http://blog.csdn.net/Super_RD/article/detai ...
- .NET文件并发与RabbitMQ(初探RabbitMQ)
本文版权归博客园和作者吴双本人共同所有.欢迎转载,转载和爬虫请注明原文地址:http://www.cnblogs.com/tdws/p/5860668.html 想必MQ这两个字母对于各位前辈们和老司 ...
- Thread.Sleep引发ThreadAbortException异常
短信平台记录日志模块,是通过异步方式来记录的,即日志工具类里初始化一个Queue对象,公共的写日志方法的处理逻辑是把日志消息放到Queue里.构造器里设定一个死循环,不停的读队,然后把日志消息持久化到 ...
随机推荐
- ThinkPHP 3.2.3(二)配置
一.配置格式 1.PHP数组定义 默认所有配置文件的定义格式均采用返回PHP数组的方式,配置参数不区分大小写. 如果使用二维数组来配置更多的信息,则二级参数配置区分大小写.格式为: //项目配置文件r ...
- ORBSLAM2与OPENCV3.1.0出错解决办法
用opencv3.1.0做ORBSLAM2运行一下命令时cd ORB_SLAM2 chmod +x build.sh ./build.sh出错:/usr/bin/ld: CMakeFiles/mono ...
- 用c++写一个广告系统
用到的基础类库 1.sstream <sstream> 库定义了三种类:istringstream.ostringstream和stringstream,分别用来进行流的输入.输出和输入输 ...
- TypeError: window.open is not a function
想必大家现在都已经到家了,而苦逼的我还要坐在办公室混拿微薄的工资,技不如人,平常不努力给自己充电,年终一毛钱都没多给.不说这扫兴的话题了,在这给同样在苦逼坚守岗位的同志们节日的问候,新的一年,好运连连 ...
- socket.io与redis构建实时推送
准备工作 1:准备nodejs环境 2:使用npm工具安装 socket.io npm install socket.io 3:下载客户端socket.io文件 解压附件中的文件 node app. ...
- Jquery挂事件与移除事件
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- maven pom.xml
什么是pom? pom作为项目对象模型.通过xml表示maven项目,使用pom.xml来实现.主要描述了项目:包括配置文件:开发者需要遵循的规则,缺陷管理系统,组织和licenses,项目的u ...
- bzoj 3530: [Sdoi2014]数数
#include<cstdio> #include<iostream> #include<cstring> #define M 1509 #define MO 10 ...
- recovery编译问题汇总
1.修改支持USB大容量存储 (1).首先需要查看手机lun位置 手机链接电脑,打开cmd命令行,依次输入以下命令: adb shell find /sys -name "lun" ...
- 【重要!】告K2老客户书
K2近期升级优化了售后支持系统,以便能更好的为亲爱的老客户们答疑解惑,比如:“老妈和老婆掉水里先救谁”.“中午吃啥晚上吃啥”.“技术男怎么学会撩妹”……这些问题,统统不会告诉你.售后TEAM作为一支专 ...