RabbitMQ使用

4 篇文章 0 订阅
3 篇文章 0 订阅

**

摘要

**
为帮助大家更为详细的了解RabbitMQ,本文会将配置以及消息发送接收的代码一并写出如下:

消息发送:

using GD.HTSupervisionModel.ApiModel;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OracleToMySQL.Common;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;

namespace OracleToMySQL.OracleToMySqlBLL
{
    public class GetOracleTableServices
    {
        IModel channel;
        IConnection Connection;
        string DirectoryPath = "../PageParams";
        MsgCenter msgCenter = new MsgCenter();
        public List<string> TableList = new List<string>();
        public IFreeSql dbContextO = StaticVariable.DBContext[StaticVariable.Oracle];
        public IFreeSql dbContextM = StaticVariable.DBContext[StaticVariable.MySql];
        ConnectionFactory Factory = new ConnectionFactory()
        {
            HostName = "localhost",//主机名,Rabbit会拿这个IP生成一个endpoint,这个很熟悉吧,就是socket绑定的那个终结点。
            UserName = "guest",//默认用户名,用户可以在服务端自定义创建,有相关命令行
            Password = "guest"//默认密码
        };
        
        /// <summary>
        /// 入口
        /// </summary>
        public GetOracleTableServices()
        {
            ServiceInit();
            Console.ReadKey();
        }

        /// <summary>
        /// 初始化
        /// </summary>
        private void ServiceInit()
        {
            var fileNames = GetFilesName(new DirectoryInfo(Readjson("filePath"))).Select(x => x.TrimEnd(".cs".ToCharArray())).ToList();

            IEnumerable<string> queueList = GetTableName().Intersect(fileNames);

            Connection = Factory.CreateConnection();    //连接服务器,即正在创建终结点。

            channel = Connection.CreateModel();

            channel.ExchangeDeclare(msgCenter.ExchangeName, "topic", true, false, null);

            foreach (var queue in queueList)
            {
                channel.QueueDeclare(queue, true, false, false, null);//创建一个名称为kibaqueue的消息队列
                channel.QueueBind(queue, msgCenter.ExchangeName, queue);    //  绑定队列至交换机
                //chanel.QueueDelete(tableName, false, false);    //清空全部队列

                Task.Factory.StartNew(() =>
                {
                    var page = GetPageParams(queue);
                    GetDataTable(queue, page);
                });

            }
        }

        /// <summary>
        /// 获取oracle数据库所有用户表
        /// </summary>
        /// <returns></returns>
        public IEnumerable<string> GetTableName()
        {
            return dbContextO.Ado.Query<string>("select table_name from user_tables").AsEnumerable();
        }

        /// <summary>
        /// 递归获取文件夹目录下所有文件名
        /// </summary>
        /// <param name="dir">遍历文件夹</param>
        /// <param name="res">返回结果</param>
        /// <returns></returns>
        public List<string> GetFilesName(DirectoryInfo dir, List<string> res = null)
        {
            if (res == null)
            {
                res = new List<string>();
            }
            // 添加当前目录文件
            FileInfo[] finfo = dir.GetFiles();
            for (int i = 0; i < finfo.Length; i++)
            {
                res.Add(finfo[i].Name);
            }
            // 查找是否有下一级目录
            var deepDir = dir.GetDirectories();
            // 有,递归调用
            if (deepDir.Length > 0)
            {
                foreach (var item in deepDir)
                {
                    res = GetFilesName(item, res);
                }
            }
            // 无,返回
            return res;
        }

        /// <summary>
        /// 格式化新旧表属性
        /// </summary>
        /// <param name="dir">遍历文件夹</param>
        /// <param name="res">返回结果</param>
        /// <returns></returns>
        public DataTable FormatObject(DataTable table, List<string> res = null)
        {
            List<string> list = new List<string>();
            for (int i = 0; i < table.Columns.Count; i++)
            {
                list.Add(table.Columns[i].ColumnName);
            }
            Type type = Assembly.Load("Models").GetTypes().FirstOrDefault(t => t.Name == table.TableName);
            if(type != null)
            {
                PropertyInfo[] properinfos = type.GetProperties();
                foreach (var item in properinfos)
                {
                    if (item.Name != "IsChecked" && item.Name != "UpdateColumns")
                    {
                        if (!list.Contains(item.Name))
                        {
                            try
                            {
                                table.Columns.Add(item.Name, item.PropertyType);
                            }
                            catch (Exception)
                            {
                                table.Columns.Add(item.Name, item.PropertyType.GenericTypeArguments[0]);
                            }
                        }
                    }
                }
            }
            return table;
        }

        /// <summary>
        /// 获取文件索引
        /// </summary>
        /// <param name="tableName"></param>
        /// <returns></returns>
        public PageParams GetPageParams(string tableName)
        {
            string filePath = $"{DirectoryPath}/{tableName}.txt";
            if (!Directory.Exists(DirectoryPath))
            {
                Directory.CreateDirectory(DirectoryPath);
            }
            if (!File.Exists(filePath))
            {
                File.CreateText(filePath).Dispose();
                File.WriteAllText(filePath, "PageIndex:1, PageSize:100");
            }
            string pageString = File.ReadAllText(filePath);
            return new PageParams()
            {
                PageIndex = Convert.ToInt32(Regex.Match(pageString, "PageIndex:\\d+").Value.Split(":").Last()),
                PageSize = Convert.ToInt32(Regex.Match(pageString, "PageSize:\\d+").Value.Split(":").Last())
            };
        }

        /// <summary>
        /// 读取表数据
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <returns></returns>
        public async void GetDataTable(string tableName, PageParams pageParams)
        {
            var table=  await getTable(tableName, pageParams);
            int rowsCount = table.Rows.Count;
          
            int count = rowsCount;
            // 数量与分页大小相同,证明表还有数据没有读完
            while (count != 0)
            {
                string filePath = $"{DirectoryPath}/{tableName}.txt";
                if (File.Exists(filePath))
                {
                    string pageString = "";
                    using (StreamReader sr = new StreamReader(filePath))
                    {
                         pageString = sr.ReadToEnd();
                    }
                    using (StreamWriter sw = new StreamWriter(filePath)) {
                        pageParams.PageIndex = Convert.ToInt32(Regex.Match(pageString, "PageIndex:\\d+").Value.Split(":").Last()) + 1;
                        pageParams.PageSize = Convert.ToInt32(Regex.Match(pageString, "PageSize:\\d+").Value.Split(":").Last());
                        sw.Write($"PageIndex:{pageParams.PageIndex}, PageSize:{pageParams.PageSize}");
                        sw.Flush();
                    }
                }
                count = table.Rows.Count;
                if (count > 0)
                {
                    string json = JsonConvert.SerializeObject(table);
                    //var insertSql = GenerateSql(json, tableName);
                    //int result = dbContextM.Ado.ExecuteNonQuery(insertSql);
                    // 发送
                    msgCenter.Content = json;
                    msgCenter.Property = channel.CreateBasicProperties();
                    msgCenter.Property.DeliveryMode = 2;
                    msgCenter.MsgTypeName = tableName;
                    await MsgSender(msgCenter);
                    
                    var methods = msgCenter.Property.GetType().GetMethods();
                    foreach (var method in methods)
                    {
                        try
                        {
                            method.Invoke(null, null);
                        }
                        catch (Exception)
                        {

                            Console.WriteLine("报错啦!");
                        }
                        
                    }

                }
                table = null;
                System.GC.Collect();
                table = await getTable(tableName, pageParams);
                Thread.Sleep(1000);
            }
        }

        /// <summary>
        /// 获取表格数据
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="pageParams"></param>
        /// <returns></returns>
        async Task<DataTable> getTable(string tableName,PageParams pageParams)
        {
            int startIndex = (pageParams.PageIndex - 1) * pageParams.PageSize;
            int endIndex = pageParams.PageIndex * pageParams.PageSize;
            string pageSql = $"select * from {tableName} where rowid in (select rid from (select rownum rn,rowid rid from {tableName}) where rn > {startIndex} and rn <= {endIndex})";
            var table = await dbContextO.Ado.ExecuteDataTableAsync(pageSql);
            if (tableName == "JGZHXY")
            {
                table.TableName = "JGZHXX";
            }
            else
            {
                table.TableName = tableName;
            }
            table = FormatObject(table);
            for (int i = 0; i < table.Rows.Count; i++)
            {
                for (int j = 0; j < table.Columns.Count; j++)
                {

                    if (string.IsNullOrWhiteSpace(table.Rows[i][table.Columns[j]].ToString()))
                    {
                        if (table.Columns[j].DataType == typeof(DateTime?) || table.Columns[j].DataType == typeof(DateTime))
                        {
                            table.Rows[i][table.Columns[j].ColumnName] = new DateTime(2000, 1, 1);
                        }
                        else if (table.Columns[j].DataType == typeof(char))
                        {
                            table.Rows[i][table.Columns[j].ColumnName] = '0';
                        }
                        else if (table.Columns[j].DataType == typeof(byte[]))
                        {
                            table.Rows[i][table.Columns[j].ColumnName] = Encoding.UTF8.GetBytes("54088");
                        }
                        else if (table.Columns[j].DataType == typeof(Decimal))
                        {
                            table.Rows[i][table.Columns[j].ColumnName] = 123.45;
                        }
                        else
                        {
                            table.Rows[i][table.Columns[j].ColumnName] = "0";
                            if (table.Columns[j].ColumnName.ToUpper() == "tenant_id".ToUpper())
                            {
                                table.Rows[i][table.Columns[j].ColumnName] = "0";
                            }
                            if (table.Columns[j].ColumnName.ToUpper() == "xzqh_id".ToUpper())
                            {
                                table.Rows[i][table.Columns[j].ColumnName] = "0";
                            }
                            //  XMTDSYZ表 ZZSJ字段用的string  但是新数据库用的mysql  有则取最后一条
                            if (tableName == "XMTDSYZ" && table.Columns[j].ColumnName == "ZZSJ" && !string.IsNullOrWhiteSpace(table.Rows[i][table.Columns[j]].ToString()))
                            {
                                table.Rows[i][table.Columns[j].ColumnName] = table.Rows[i][table.Columns[j].ColumnName].ToString().Split(',').Last();
                            }
                        }
                    }
                }
            }
            return table;
        }

        /// <summary>
        /// 读取JSON文件
        /// </summary>
        /// <param name="key">JSON文件中的key值</param>
        /// <returns>JSON文件中的value值</returns>
        public static string Readjson(string key)
        {
            string jsonfile = "../../../appsetting.json";//JSON文件路径

            using (System.IO.StreamReader file = System.IO.File.OpenText(jsonfile))
            {
                using (JsonTextReader reader = new JsonTextReader(file))
                {
                    JObject o = (JObject)JToken.ReadFrom(reader);
                    var value = o[key].ToString();
                    return value;
                }
            }
        }
        
        #region 消息队列
        /// <summary>
        /// 消息队列发送服务
        /// </summary>
        public Task MsgSender(MsgCenter msgCenter)
        {
            channel.BasicPublish(msgCenter.ExchangeName, msgCenter.MsgTypeName, msgCenter.Property, Encoding.UTF8.GetBytes(msgCenter.Content)); //生产消息
            return Task.CompletedTask;
        }
        #endregion

    }
}

消息接收:

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OracleToMySQL.Common;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace CustomsMQ
{
    public class Custom
    {
        public IModel channel { get; set; }
        public EventingBasicConsumer customer { get; set; }
    }

    public class RabbitMQCutsom
    {
        //定义一个私有成员变量,用于Lock  
        IEnumerable<string> names;
        private static object lockobj = new object();
        private IFreeSql dbContextM = StaticVariable.DBContext[StaticVariable.MySql];
        private Dictionary<string, Custom> Channel = new Dictionary<string, Custom>();
        IConnection Connection = new ConnectionFactory()
        {
            HostName = "localhost",
            UserName = "guest",
            Password = "guest"
        }.CreateConnection();
        string Exchange = "myExchange";

        public void Run()
        {
            RabbitMQCutsom services = new RabbitMQCutsom();
            names = services.getNameList().Select(x => x.ToUpper());
            IModel channel = Connection.CreateModel();  //  创建连接

            foreach (var tableName in names)
            {
                #region 初始化消费者
                channel.ExchangeDeclare(Exchange, "topic", true, false, null);
                channel.QueueBind(tableName, Exchange, tableName);
                #endregion
            }
            var consumer = new EventingBasicConsumer(channel);  //  消费者


            consumer.Received += (ch, ea) =>
            {
                lock (lockobj)
                {
                    string errMsg = string.Empty;
                    string message = Encoding.Default.GetString(ea.Body.ToArray());
                    if (!string.IsNullOrWhiteSpace(message))
                    {
                        //InsertData(message, msgCenter.MsgTypeName, ref errMsg);

                        //  消费完成
                        //if (string.IsNullOrWhiteSpace(errMsg))
                        //{
                        //    Console.WriteLine($"写入成功:{msgCenter.MsgTypeName}");
                        //}
                        if (!string.IsNullOrWhiteSpace(message))
                        {

                            //通过反射跨类库拿实体
                            Assembly assembly = Assembly.LoadFrom("Models");

                            Type instanceType = assembly.GetType($"GD.NP.FDCSCJG.Models.{ea.RoutingKey}");
                            var instanceTypes = Type.GetType($"System.Collections.Generic.List`1[[{instanceType.AssemblyQualifiedName}]]");

                            var instanceDatas = Newtonsoft.Json.JsonConvert.DeserializeObject(message, instanceTypes);
                            List<object> objList = ((IEnumerable<object>)instanceDatas).ToList();
                            var properties = objList[0].GetType().GetProperties();
                            foreach (var obj in objList)
                            {
                                foreach (var property in properties)
                                {
                                    if (property.Name == "SFYC" || property.Name == "SFDT" || property.Name == "SFTY" || property.Name == "SFZX")
                                    {
                                        property.SetValue(obj, property.GetValue(obj).ToString().ElementAt(0).ToString());
                                    }
                                    else if (property.Name == "ZZSJ")
                                    {
                                        property.SetValue(obj, property.GetValue(obj).ToString().Split(',').ElementAt(0));
                                    }
                                    else
                                    {
                                        property.SetValue(obj, property.GetValue(obj));
                                    }
                                }
                            }

                            //通过反射拿方法
                            var insertMethod = dbContextM.GetType().GetMethods()
                                        .Where(o => o.Name == "Insert"
                                            && o.GetParameters().Where(p => p.ParameterType.Name == "List`1").ToList().Count == 1
                                            && o.GetGenericArguments().Length == 1
                                        ).FirstOrDefault();

                            var insertGenericMethod = insertMethod.MakeGenericMethod(instanceType);
                            var iInsert = insertGenericMethod.Invoke(dbContextM, new object[] { instanceDatas });

                            var iInsertType = iInsert.GetType();
                            var executeAffrowsMethod = iInsertType.GetMethods()
                                                                  .Where(o => o.Name == "ExecuteAffrows" && o.GetGenericArguments().Length == 0)
                                                                  .FirstOrDefault();
                            try
                            {
                                var resultInsert = executeAffrowsMethod.Invoke(iInsert, null);
                                Console.WriteLine($"{ea.RoutingKey}成功!");
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine($"{ea.RoutingKey}插入失败了:{ex.Message}");
                            }


                            //channel.BasicAck(ea.DeliveryTag, false);
                        }
                    }
                    // 有的数据之前已经插入过表 不需要确认 以免造成消息积压
                    //Channel[msgCenter.MsgTypeName].channel.BasicAck(ea.DeliveryTag, false);
                    message = null;
                    errMsg = null;
                    Thread.Sleep(1000);
                    System.GC.Collect();
                }
            };

            //启动消费者 设置为手动应答消息
            foreach (var tableName in names)
            {
                channel.BasicConsume(tableName, true, consumer);
            }

            Console.ReadKey();
        }

        /// <summary>
        /// 获取数据库所有表名
        /// </summary>
        /// <returns></returns>
        public List<string> getNameList()
        {
            return dbContextM.Ado.Query<string>("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='gd_bdcfc_fcscjg'");
        }
    }

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值