using Cksoft.Unity; 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; using System.Text; namespace DllEapBll.SignalR { public class LogServer { 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 LogServer() { } //开始接收队列线程 public int StartRecQueue(ref string errorinfo) { try { CurrRecQueueName = AppConfigurtaionServices.Configuration["mqname:logmqname"]; //注册通道 CurrQueueChannel = RegeditChannel(ref errorinfo); if (CurrQueueChannel == null) { errorinfo = "注册队列通道发生错误,错误信息为:" + errorinfo; return -1; } //同样要声明交换机的类型及名称,不然publish和consumer匹配不上 // exchange 交换机名称 type交换机类型fanout、direct、topic CurrQueueChannel.ExchangeDeclare(exchange: "AllExchang", type: "fanout"); //声明一个队列,这个队列的名称随机 var queueName = CurrQueueChannel.QueueDeclare().QueueName; //将这个队列绑定(bind)到交换机上面 CurrQueueChannel.QueueBind(queue: queueName, exchange: "AllExchang", routingKey: ""); //CurrQueueChannel.QueueDeclare(queueName, false, false, false, null); //BasicQos函数是针对通道的,必须放在注册消费者前执行,否则注册的消费者会接受多条信息 // 第一个参数可接受消息的大小 第二个参数处理消息最大数量 第三个参数是不是针对整个Connection CurrQueueChannel.BasicQos(0, 1, false); //生命一个consumer var consumer = new EventingBasicConsumer(CurrQueueChannel); CurrQueueChannel.BasicConsume(queue: queueName, 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 = "127.0.0.1";//AppConfigurtaionServices.Configuration["rabbitmq:IPAddress"]; factory.UserName = "guest";// AppConfigurtaionServices.Configuration["rabbitmq:UserName"]; factory.Password = "guest"; //AppConfigurtaionServices.Configuration["rabbitmq:Password"]; 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); } //public async Task GetLogStatus(string filter) //{ // EapResponse response = null; // var connectionId = Context.ConnectionId; // try // { // await Clients.Client(connectionId).SendAsync("ReceiveUpdate", response); // } // catch (Exception e) // { // await Clients.Client(connectionId).SendAsync("Error", e.Message); // } // finally // { // await Clients.Client(connectionId).SendAsync("Finished"); // Dispose(); // } //} private int WriteLog(byte[] datas, ref string errorinfo) { try { string hs = Encoding.UTF8.GetString(datas.ToArray()); var b= Json.ToObject(hs); HsmsLog log = Json.ToObject(hs); // HsmsLog log = EntityHelper.DeSerializeBytes(datas); if(!string.IsNullOrEmpty(log.Log)) { //LogHub logHub = new LogHub(); //Task.Run(()=> logHub.GetLogStatus(log)); } //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) //{ // //如果是测试指令,则不记录日志 // if (orgblock.GetBlockS(ref errorinfo) == 0) // return 1; //} //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} 信息:{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 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["mqname:logmqname"]; 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; } } } }