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里.构造器里设定一个死循环,不停的读队,然后把日志消息持久化到 ...
随机推荐
- CentOS_7.2安装PHP_5.6
一.安装依赖包和开发工具: yum install vim vim-enhanced wget zip unzip telnet ntsysv compat* apr* nasm* gcc gcc* ...
- 程设大作业xjb写——魔方复原
鸽了那么久总算期中过[爆]去[炸]了...该是时候写写大作业了 [总不能丢给他们不会写的来做吧 一.三阶魔方的几个基本定义 ↑就像这样,可以定义面的称呼:上U下D左L右R前F后B UD之间的叫E,LR ...
- iOS/OSX学习资源
https://www.raywenderlich.com/ (Ray视频教学) http://wiki.jikexueyuan.com/project/swift/ (swift中文学习网站)
- Python查找当前路径和子路径下指定后缀名的文件
# -*- encoding:utf-8 -*- import os def SearchFile(path,text): try: files=os.listdir(path) for f in f ...
- CALayer 详解 -----转自李明杰
本文目录 一.什么是CALayer 二.CALayer的简单使用 回到顶部 一.什么是CALayer * 在iOS系统中,你能看得见摸得着的东西基本上都是UIView,比如一个按钮.一个文本标签.一个 ...
- 用HTML做的简单的个人简历
<html> <head> <title>table表格</title> <style type="text/css"> ...
- OC基础--结构体 枚举做类成员属性
结构体 枚举作类的成员属性: 定义一个学生类 性别 -- 枚举 生日 入学日期 毕业日期 -- 结构体 代码示例: 声明文件 Student.h: #import <Foundation ...
- HPL/SQL与CDH5.4.7集成
1.下载hplsql-0.3.13到本地并解压 2.修改plsql,为如下内容 #!/bin/bash export "HADOOP_CLASSPATH=/opt/cloudera/parc ...
- Asp.net MVC 数据注解与验证
数据注解特性定义在名称空间System.ComponentModel.DataAnnotations中(有些特性定义在其他名称空间中),它们提供了服务器端验证的功能,当在模型的属性上使用这些特性时,框 ...
- ios中文转码的一个奇葩问题
事情是这样的:我要在一个URL中截取一个名为‘vfname’的参数,因为这个参数的值带有中文(转码之前的形式),所以我必须将其转码. URL是这样的: http://devapi.amibaguanl ...

