using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Text;
namespace tool
{
    delegate void DelegateCallbacks(string msg, ref IModel channel, ref BasicDeliverEventArgs args);
    class consumer//消费者
    {
        public consumer()
        { 
        }
        public void consumer_init(string ip, int port, string user, string password, string queue_key, DelegateCallbacks callbacks)
        {
            m_ip = ip;
            m_port = port;
            m_user = user;
            m_password = password;
            m_delegateCallbacks = callbacks;
            m_queue_key = queue_key;
        }
        public void run()
        {
            Console.WriteLine(" create connection ");
            m_connectionFactory = new ConnectionFactory();
            m_connectionFactory.HostName = m_ip;//RabbitMQ地址
            m_connectionFactory.UserName = m_user;//RabbitMQ用户
            m_connectionFactory.Port = m_port;//RabbitMQ用户
            m_connectionFactory.Password = m_password;//RabbitMQ用户密码

            m_connection = m_connectionFactory.CreateConnection();
            m_channel = m_connection.CreateModel();//创建连接会话对象
            m_channel.BasicQos(0, 1, false);//声明为手动确认，每次只消费1条消息。
            var consumer = new EventingBasicConsumer(m_channel);//定义消费者
                                                                //接收时间
            consumer.Received += (eventSender, args) => {
                //获取消息
                var message = args.Body;//获取队列中消息主体
                                                     //处理消息
                m_delegateCallbacks(Encoding.UTF8.GetString(message.ToArray()),ref m_channel,ref args);

            };
            Console.WriteLine("start consume queue:" + m_queue_key);
            //开启监听
            m_channel.BasicConsume(queue: m_queue_key, autoAck: false, consumer: consumer);

        }
        private string m_ip;
        private int m_port;
        private string m_user;
        private string m_password;
        private string m_queue_key;
        private DelegateCallbacks m_delegateCallbacks;
        private ConnectionFactory m_connectionFactory;
        private IConnection m_connection;
        private IModel m_channel;
    }

    class consumer_undurable
    {
        public consumer_undurable()
        {
        }
        public void consumer_undurable_init(string ip, int port, string user, string password, string ex_name, string routingkey, DelegateCallbacks callbacks)
        {
            m_ip = ip;
            m_port = port;
            m_user = user;
            m_password = password;
            m_ex_name = ex_name;
            m_routingkey = routingkey;
            m_delegateCallbacks = callbacks;
        }
        public void run()
        {
            m_connectionFactory = new ConnectionFactory();
            m_connectionFactory.HostName = m_ip;//RabbitMQ地址
            m_connectionFactory.UserName = m_user;//RabbitMQ用户
            m_connectionFactory.Port = m_port;//RabbitMQ用户
            m_connectionFactory.Password = m_password;//RabbitMQ用户密码

            m_connection = m_connectionFactory.CreateConnection();
            m_channel = m_connection.CreateModel();//创建连接会话对象
            
            string queue=m_channel.QueueDeclare("", false, false, false, null);
            m_channel.QueueBind(queue, m_ex_name, m_routingkey, null);//设置routingkey（可不同的消息发往不同的队列）  info：为正常的消息

            var consumer = new EventingBasicConsumer(m_channel);//定义消费者
                                                                //接收时间
            consumer.Received += (eventSender, args) => {
                //获取消息
                var message = args.Body;//获取队列中消息主体
                                        //处理消息
                m_delegateCallbacks(Encoding.UTF8.GetString(message.ToArray()), ref m_channel, ref args);

            };
            Console.WriteLine("create queue to consume ex:"+m_ex_name +"port:" +m_port);         //开启监听
            m_channel.BasicConsume(queue: queue, autoAck: false, consumer: consumer);

        }
        private string m_ip;
        private int m_port;
        private string m_user;
        private string m_password;
        private string m_ex_name;
        private string m_routingkey;
        private DelegateCallbacks m_delegateCallbacks;
        private ConnectionFactory m_connectionFactory;
        private IConnection m_connection;
        private IModel m_channel;
    }

    class producer
    {
        public producer()
        {
        }
        public void producer_init(string ip, int port, string user, string password)
        {
            m_ip = ip;
            m_port = port;
            m_user = user;
            m_password = password;
            m_connectionFactory = new ConnectionFactory();
            m_connectionFactory.HostName = m_ip;//RabbitMQ地址
            m_connectionFactory.UserName = m_user;//RabbitMQ用户
            m_connectionFactory.Port = m_port;//RabbitMQ用户
            m_connectionFactory.Password = m_password;//RabbitMQ用户密码

            m_connection = m_connectionFactory.CreateConnection();
            m_channel = m_connection.CreateModel();//创建连接会话对象

        }
        public bool send(string message,string ex_name,string routingkey)
        {

            if (m_connection.IsOpen && m_channel.IsOpen)
            {
                var body = Encoding.UTF8.GetBytes(message);
                m_channel.BasicPublish(ex_name, routingkey, false, null, body);
            }
            else
            {
                m_connectionFactory = new ConnectionFactory();
                m_connectionFactory.HostName = m_ip;//RabbitMQ地址
                m_connectionFactory.UserName = m_user;//RabbitMQ用户
                m_connectionFactory.Port = m_port;//RabbitMQ用户
                m_connectionFactory.Password = m_password;//RabbitMQ用户密码
                try
                {
                    m_connection = m_connectionFactory.CreateConnection();
                    m_channel = m_connection.CreateModel();//创建连接会话对象
                    var body = Encoding.UTF8.GetBytes(message);
                    m_channel.BasicPublish(ex_name, routingkey, false, null, body);
                }
                catch
                {
                    return false;
                }
            }
            return true;
        }
        private string m_ip;
        private int m_port;
        private string m_user;
        private string m_password;
        private ConnectionFactory m_connectionFactory;
        private IConnection m_connection;
        private IModel m_channel;
    }
}












