using Cksoft.Data; using Cksoft.Data.Repository; using Cksoft.Unity; using DllEapDal; using DllEapEntity; using DllHsms; using Microsoft.Extensions.Logging; using RabbitMQ.Client; using RabbitMQ.Client.Events; using System; using System.Collections.Generic; using System.IO; using System.Linq; namespace DllLogServer { public class LogServer:ILogServer { private ILogger loger = null; private long CurrCount = 0; private IModel CurrQueueChannel = null; private string CurrRecQueueName = "hello";//接收队列名称 hsmsreceive+机台编号 private List CurrInfo = new List();//记录错误信息 private int CurrStatus = -1;//未启动状态 private string CurrFileDir="";//日志文件主路径 public string CurrShareFileDir = ""; public LogServer(ILogger loger) { this.loger = loger; } //开始接收队列线程 public int StartRecQueue(ref string errorinfo) { try { //注册通道 CurrQueueChannel = RegeditChannel(ref errorinfo); if (CurrQueueChannel == null) { errorinfo = "注册队列通道发生错误,错误信息为:" + errorinfo; return -1; } //清空接收队列 //int result = ClearRecQueue(ref errorinfo); //if (result < 0) //{ // errorinfo = "清空接收队列发生错误,错误信息为:" + errorinfo; // return -1; //} CurrQueueChannel.QueueDeclare(CurrRecQueueName, false, false, false, null); //BasicQos函数是针对通道的,必须放在注册消费者前执行,否则注册的消费者会接受多条信息 CurrQueueChannel.BasicQos(0, 1, false); var consumer = new EventingBasicConsumer(CurrQueueChannel); CurrQueueChannel.BasicConsume(queue: CurrRecQueueName, autoAck: false, //是否不要手动应答(no manual Ack),ture自动应答,自动删除处理消息;false手动应答,服务器的消息会等待应答结果才消除 consumer: consumer); consumer.Received += QueueReceive; return 1; } catch (Exception ex) { errorinfo = ex.Message.ToString(); return -1; } } //注册通道 private IModel RegeditChannel(ref string errorinfo) { try { var factory = new ConnectionFactory(); factory.HostName = AppConfigurtaionServices.Configuration["rabbitmq:IPAddress"]; factory.UserName = AppConfigurtaionServices.Configuration["rabbitmq:UserName"]; factory.Password = AppConfigurtaionServices.Configuration["rabbitmq:Password"]; factory.VirtualHost = AppConfigurtaionServices.Configuration["rabbitmq:VirtualHost"]; var connection = factory.CreateConnection(); var channel = connection.CreateModel(); CurrShareFileDir = AppConfigurtaionServices.Configuration["ShareFileDir"]; return channel; } catch (Exception ex) { errorinfo = ex.Message.ToString(); return null; } } private int ClearRecQueue(ref string errorinfo) { try { CurrQueueChannel.QueueDelete(CurrRecQueueName, true, false); return 1; } catch (Exception ex) { errorinfo = ex.Message.ToString(); return -1; } } private void QueueReceive(object model, BasicDeliverEventArgs ea) { CurrCount++; string errorinfo = ""; int result = WriteLog(ea.Body, ref errorinfo); if (result <= 0) { //写本地日志 SetText(errorinfo); } CurrQueueChannel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false); } private int WriteLog(byte[] datas, ref string errorinfo) { try { HsmsLog log = EntityHelper.DeSerializeBytes(datas); int result = log.RecoverData(CurrShareFileDir, ref errorinfo); if (result <= 0) return -1; int ftype = log.FType;// int.Parse(row["ftype"].ToString()); int mcaid = log.MacID;// int.Parse(row["mcaid"].ToString()); string logstr = log.Log;// row["log"].ToString(); string fcode = log.MacCode;// row["fcode"].ToString(); Block orgblock = log.OrgBlock;//通讯块 if(orgblock!=null&&orgblock.AllLen>1000) { int aaa = 100; } if (orgblock != null) { //如果是测试指令,则不记录日志 if (orgblock.GetBlockS(ref errorinfo) == 0) return 1; // UpdateVersion(orgblock, mcaid); } DateTime occurtime = log.OccurTime;//发生时间 string filename = GetLogFile(mcaid, fcode, ref errorinfo); if (filename == "") return -1; logstr = $"发生时间:{occurtime.ToString("yyyy-MM-dd HH:mm:ss.fff")} 机台ID:{mcaid} 机台编号:{fcode} 机台IP:{log.macOrder.IPAddress} 信息:{logstr}"; FileStream fs; StreamWriter sw; if (File.Exists(filename)) { //验证文件是否存在,有则追加,无则创建 fs = new FileStream(filename, FileMode.Append, FileAccess.Write); } else { fs = new FileStream(filename, FileMode.Create, FileAccess.Write); } sw = new StreamWriter(fs); sw.WriteLine(logstr); if (orgblock != null) { //打印指令数据 logstr = orgblock.GetLog(log.Log); sw.WriteLine(logstr); } sw.Close(); fs.Close(); return 1; } catch (Exception ex) { errorinfo = ex.Message.ToString(); return -1; } } private void UpdateVersion(Block orgblock,int macid) { IDatabase db = null; try { string errorinfo = ""; int s = orgblock.GetBlockS(ref errorinfo); int f = orgblock.GetBlockF(ref errorinfo); if (!(s == 1 && f == 2)) return; List datas = orgblock.GetOrderData(ref errorinfo); OrderData l = datas.Where(t => t.ParentID == 0).FirstOrDefault(); List tempdatas = datas.Where(t => t.ParentID == l.ID).OrderBy(t => t.FNum).ToList(); db = DbFactory.Base("eap"); Machine mac = db.FindEntity(macid); if (mac.FVersion == tempdatas[1].FContent) { return; } db.BeginTrans(); mac.FName = tempdatas[0].FContent; mac.FVersion = tempdatas[1].FContent; db.UpdateFor(mac, ""); db.Commit(); } catch(Exception ex) { loger.LogError(ex.ToString()); } finally { if (db != null) db.Close(); } } private string GetLogFile(int mcaid, string code, ref string errorinfo) { try { //每天1个日志 string sFilePath = $"{CurrFileDir}{Path.DirectorySeparatorChar}log{DateTime.Now.ToString("yyyyMMdd")}";// CurrFileDir + "log" + DateTime.Now.ToString("yyyyMMdd"); string sFileName = $"{code}_{mcaid}.log"; sFileName = sFilePath + Path.DirectorySeparatorChar + sFileName; //文件的绝对路径 if (!Directory.Exists(sFilePath))//验证路径是否存在 { Directory.CreateDirectory(sFilePath); //不存在则创建 } return sFileName; } catch (Exception ex) { errorinfo = ex.Message.ToString(); return ""; } } public void SetText(string str) { this.loger.LogError(str); if (CurrInfo.Count > 100) CurrInfo.Clear(); int id = 1; if (CurrInfo.Count > 0) { id = CurrInfo.Max(t => t.ID); id++; } ServerInfo entity = new ServerInfo(); entity.ID = id; entity.Info = str; CurrInfo.Add(entity); } public int Start(ref string errorinfo) { try { CurrStatus = -1; CurrRecQueueName = AppConfigurtaionServices.Configuration["rabbitmq:mqname"]; CurrFileDir = AppConfigurtaionServices.Configuration["FileDir"]; int result = StartRecQueue(ref errorinfo); if (result < 0) { errorinfo = $"启动失败,错误信息为:{errorinfo}"; SetText(errorinfo); return -1; } CurrStatus = 1; SetText("启动成功。"); return 1; } catch (Exception ex) { errorinfo = ex.Message.ToString(); SetText(errorinfo); return -1; } } public long GetAccount() { return CurrCount; } public int GetStatus(ref string errorinfo) { if (CurrStatus <= 0 && CurrInfo.Count > 0) { errorinfo = CurrInfo.Last().Info; } return CurrStatus; } public List GetInfo() { return CurrInfo; } public int Stop(ref string errorinfo) { try { CurrStatus = -1; if (CurrQueueChannel != null) CurrQueueChannel.Close(); SetText("停止服务成功。"); return 1; } catch (Exception ex) { SetText(ex.Message.ToString()); return -1; } } } }