Files
2025-11-26 13:45:58 +08:00

2292 lines
107 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Fleck;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using WebSocketToolsConsole;
using System.Runtime.Serialization;
//using static System.Net.Mime.MediaTypeNames;
using static WebSocketToolsConsole.Entity;
using System.Drawing.Imaging;
using System.Drawing;
using Face.Web.Areas.App.Models;
using System.Linq;
using Newtonsoft.Json.Linq;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
using System.Buffers.Text;
using Org.BouncyCastle.Bcpg;
using System.Data.Entity.Core.Metadata.Edm;
using System.Collections.Concurrent;
using Org.BouncyCastle.Asn1.Tsp;
using System.Runtime.CompilerServices;
using System.Messaging;
using System.Web.UI.WebControls.WebParts;
using System.Net.Http;
namespace TestWebSocket
{
public class SocketCount
{
public string path { get; set; }
public int count { get; set; }
}
public partial class Program
{
//有几台设备连接,出错,再连接,再出错。会影响控制台逻辑处理,
//经过日志分析后,确认这样的设备不再处理,放到这个表里面。
//在处理到这样的设备时,一律不做处理。
private static List<String> NoProcessSN;
//链路表和链路表表级别锁。
//表级别锁,用在两处:
//1. 收到新建链路请求,将新建链路保存到链路表的时候。
//2. 收到关闭链路请求,将已建链路,不存在链路清空,可能会影响链路表。
private static Object dicSocksLock = new Object();
private static Dictionary<String, IWebSocketConnection> _dicSockets;
private static string SerialNo2 = "";
//每个表初始化清理的时候用表级别锁
//每个链路的ping计数时使用行锁pingCount[currentLinkKey]
private static int pingLinkNum = 0;
private static SocketCount[] pingCount = new SocketCount[4096]; //所有链路ping计数表。预留4096个位置我们现在大概有690个设备。
private static Dictionary<string, int> reverseDic = new Dictionary<string, int>();//所有链路ping计数表的反向映射以便快速找到对象。
private static Dictionary<string, bool> _dicSocketsPingLastStat; //所有链路历史状态表,用来做比较反转。
private static int pingCountLowValue = 3; //活的门槛值30秒一次ping两分钟内应该收到4到5次大于等于3次就认为活。
public static System.Threading.Timer gDeviceCheckPingTimer = null;
public class FactoryAndSn
{
public string factory;
public string sn;
}
static void Main(string[] args)
{
//每次重启把所有状态设置成不在线。
//稍后的服务器会和每个活动的设备通信,获得正确的状态。
//永远不活动的不会被设置状态,就是保持不在线状态
//本地测试时需要注释这个方法
SetAllStatusToInactive();
//Thread 1 Read Command from MessageQueue which is original from web server interface.
//read, sleep 1 second, then again
Thread revT = new Thread(ReceiveCmdLoop);
revT.Start();
//Timmer on thread pool for Web Socket server logging
//Delay 5 minuutes to give enough time for the connection established and finished the 1st ping count time period.
gDeviceCheckPingTimer = new System.Threading.Timer(WritePingStatusToDB, null, 5 * 60 * 1000, 4 * 30 * 1000);
//Thread2 as Web Socket server
Index();
//Main thread block at keyboard input
while (true)
{
var set = Console.ReadLine();
if (set == "1")
{
GetUIwordSand();
Console.WriteLine("到此");
}
if (set == "2")
{
GetUiImgdSand();
Console.WriteLine("2到此");
}
}
;
}
public static string queueName = @".\private$\facesvrcmd";
public static MessageQueue mq = null;
public static string queueName2 = @".\private$\faceServerToWeb";
public static MessageQueue mq2 = null;
/// <summary>
/// 从消息队列中读取命令,并执行
/// </summary>
public static void ReceiveCmdLoop()
{
while (true)
{
try
{
//判断队列是否存在
if (MessageQueue.Exists(queueName))
{
mq = new MessageQueue(queueName);
}
else
{
//创建队列
mq = MessageQueue.Create(queueName);
}
//给管理员队列权力
mq.SetPermissions("Administrator", MessageQueueAccessRights.FullControl);
//匿名登录
mq.SetPermissions("ANONYMOUS LOGON", MessageQueueAccessRights.FullControl);
mq.SetPermissions("Everyone", MessageQueueAccessRights.FullControl);
while (true)
{
Message msgRx = mq.Receive();
msgRx.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
string strRx = msgRx.Body.ToString();
LogHelper.WriteLine("mq.Receive = " + strRx);
processWebCmdOneThreadByMSMQ(strRx);
Thread.Sleep(1300); //阻塞当前线程1秒让其他线程运行
}
}
catch (Exception ex)
{
LogHelper.WriteLine("控制台程序从Web程序通过消息队列读取命令线程异常被重新启动。异常" + ex.Message);
Thread.Sleep(5000); //阻塞当前线程5秒再重新启动
continue;
}
}
}
/// <summary>
/// 向消息队列中发送消息
/// </summary>
/// <param name="sendMsg">消息</param>
/// <returns></returns>
public static string QueueSend(string sendMsg)
{
try
{
if (mq2 == null)
{
if (MessageQueue.Exists(queueName2))
{
mq2 = new MessageQueue(queueName2);
}
else
{
mq2 = MessageQueue.Create(queueName2);
}
mq2.SetPermissions("Administrator", MessageQueueAccessRights.FullControl);
mq2.SetPermissions("ANONYMOUS LOGON", MessageQueueAccessRights.FullControl);
mq2.SetPermissions("Everyone", MessageQueueAccessRights.FullControl);
}
Message msgTx = new Message
{
Body = sendMsg,
Formatter = new XmlMessageFormatter(new Type[] { typeof(string) })
};
mq2.Send(msgTx);
return "Succeed push msg to MQ !";
}
catch (Exception ex)
{
mq2 = null;
LogHelper.WriteLine("控制台程序给Web程序通过消息队列发送信息线程报错。异常" + ex.Message);
return ex.ToString();
}
}
/// <summary>
///接收和处理wed端发送数据的方法
/// </summary>
/// <param name="receiveString">wed端发送的参数字符串</param>
public static void processWebCmdOneThreadByMSMQ(string receiveString)
{
string id = "";
Entity.Rootinfo Elist = JsonConvert.DeserializeObject<Entity.Rootinfo>(receiveString);//josn转换实体类
Entity.Rootinfo NoPhotoElist = JsonConvert.DeserializeObject<Entity.Rootinfo>(receiveString);
//msginfo info = JsonConvert.DeserializeObject<msginfo>(NoPhotoElist.msgx.msg);
string[] arr = NoPhotoElist.msgx.msg.Split('&');
if (arr[0] == "key=abcdef")
{
id = Elist.msgx.msgid;
string serializerinfo = "";//对象转换josn
string serializerIgnorImageForLoginfo = "";
if (Elist.msgx.cmd == "GetModelInfo")
{
Sendmessageinfo deviceinfo = new Sendmessageinfo();
deviceinfo.SN = Elist.msgx.sn;
deviceinfo.CMD = "GetModelInfo";
deviceinfo.MsgID = Guid.NewGuid().ToString();
deviceinfo.Para.Key = "abc";
deviceinfo.Token = "Boonlive JSON command system";
deviceinfo.ProtocolVersion = "2.1";
deviceinfo.DateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
deviceinfo.Brand = "yh";
serializerinfo = JsonConvert.SerializeObject(deviceinfo);//对象转换josn
serializerIgnorImageForLoginfo = JsonConvert.SerializeObject(deviceinfo);
}
else if (Elist.msgx.cmd == "SetUI")
{
string[] strarr = arr[1].Split('=');
datainfo infos = JsonConvert.DeserializeObject<datainfo>(strarr[1]);
var imageBj = "";
var imagelogo = "";
string str1 = "";
string str2 = "";
string str3 = "";
string str4 = "";
if (!string.IsNullOrEmpty(infos.imageBj))
{
str1 = infos.imageBj.Substring(infos.imageBj.IndexOf("<"), infos.imageBj.IndexOf(">") - infos.imageBj.IndexOf("<") + 1);
str3 = infos.imageBj.Substring(infos.imageBj.IndexOf("<") + 1, infos.imageBj.IndexOf(">") - 1);
imageBj = Program.YHFileImage(str3);
}
if (!string.IsNullOrEmpty(infos.imagelogo))
{
str2 = infos.imagelogo.Substring(infos.imagelogo.IndexOf("<"), infos.imagelogo.IndexOf(">") - infos.imagelogo.IndexOf("<") + 1);
str4 = infos.imagelogo.Substring(infos.imagelogo.IndexOf("<") + 1, infos.imagelogo.IndexOf(">") - 1);
//var imageBj = Program.YHFileImage(str3);
imagelogo = Program.YHFileImage(str4);
}
SenbJandrnameandlogo sabaral = new SenbJandrnameandlogo();
sabaral.SN = Elist.msgx.sn;
sabaral.CMD = "SetUI";
sabaral.MsgID = Guid.NewGuid().ToString();
sabaral.Token = "Boonlive JSON command system";
sabaral.ProtocolVersion = "2.1";
sabaral.DateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
sabaral.Brand = "yh";
sabaral.Para.Key = "abc";
sabaral.Para.Logo = imagelogo;
sabaral.Para.BkgImg = imageBj;
sabaral.Para.RoomNo = infos.Roomname;
//下发内容
serializerinfo = JsonConvert.SerializeObject(sabaral);//对象转换josn
//日志内容
serializerIgnorImageForLoginfo = JsonConvert.SerializeObject(sabaral);
if (imagelogo.Length != 0)
{
serializerIgnorImageForLoginfo = serializerIgnorImageForLoginfo.Replace(imagelogo, "PHOTO_IMAGE_AT_HERE_WITH_LENGTH_" + imagelogo.Length);
}
if (imageBj.Length != 0)
{
serializerIgnorImageForLoginfo = serializerIgnorImageForLoginfo.Replace(imageBj, "PHOTO_IMAGE_AT_HERE_WITH_LENGTH_" + imageBj.Length);
}
}
else if (Elist.msgx.cmd == "RestoreFactorySetting")
{
Sendmessageinfo deviceinfo = new Sendmessageinfo();
deviceinfo.SN = Elist.msgx.sn;
deviceinfo.CMD = "RestoreFactorySetting";
deviceinfo.MsgID = Guid.NewGuid().ToString();
deviceinfo.Para.Key = "abc";
deviceinfo.Token = "Boonlive JSON command system";
deviceinfo.ProtocolVersion = "2.1";
deviceinfo.DateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
deviceinfo.Brand = "yh";
serializerinfo = JsonConvert.SerializeObject(deviceinfo);//对象转换josn
serializerIgnorImageForLoginfo = JsonConvert.SerializeObject(deviceinfo);
}
else if (Elist.msgx.cmd == "UploadLogData")
{
SendUpData send = new SendUpData();
send.SN = Elist.msgx.sn;
send.CMD = "UploadLogData";
send.MsgID = Guid.NewGuid().ToString();
send.Token = "Boonlive JSON command system";
send.ProtocolVersion = "2.1";
send.DateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
send.Brand = "yh";
send.Para.Key = "abc";
string[] strarr1 = arr[1].Split('=');
send.Para.Host = strarr1[1];
string[] strarr2 = arr[3].Split('=');
send.Para.Port = strarr2[1];
string[] strarr3 = arr[2].Split('=');
send.Para.UserName = strarr3[1];
string[] strarr4 = arr[4].Split('=');
send.Para.PW = strarr4[1] + "&" + arr[5];
string[] strarr5 = arr[6].Split('=');
send.Para.Folder = strarr5[1];
serializerinfo = JsonConvert.SerializeObject(send);//对象转换josn
serializerIgnorImageForLoginfo = JsonConvert.SerializeObject(send);
}
else if (Elist.msgx.cmd == "updateAPK2")
{
SendUpDataAPK send = new SendUpDataAPK();
send.SN = Elist.msgx.sn;
send.CMD = "updateAPK2";
send.MsgID = Guid.NewGuid().ToString();
send.Token = "Boonlive JSON command system";
send.ProtocolVersion = "2.1";
send.DateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
send.Brand = "yh";
send.Para.Key = "abc";
string[] strarr1 = arr[2].Split('=');
send.Para.Host = strarr1[1];
string[] strarr2 = arr[4].Split('=');
send.Para.Port = strarr2[1];
string[] strarr3 = arr[3].Split('=');
send.Para.UserName = strarr3[1];
string[] strarr4 = arr[5].Split('=');
send.Para.PW = strarr4[1] + "&" + arr[6]; ;
string[] strarr5 = arr[1].Split('=');
send.Para.File = strarr5[1];
serializerinfo = JsonConvert.SerializeObject(send);//对象转换josn
serializerIgnorImageForLoginfo = JsonConvert.SerializeObject(send);
}
pmsProcess pmsinfo = new pmsProcess()
{
messageid = id,
issuestate = 0,
receive = 1,
Issueface = 0,
cmdType = Elist.msgx.cmd
};
//BLL.pmsmemory(pms);
//发送确认
//LogHelper.WriteLine("到 4");
SendWebDatabase(new Entity.msgx
{
msgid = Elist.msgx.msgid,
cmd = "0",
msg = "已收到..."
});
SendWebDatabase(new Entity.msgx
{
msgid = Elist.msgx.msgid,
cmd = "1",
msg = "正处理..."
});
//LogHelper.WriteLine("到 5");
//if (Elist.pmsid != -1)
//{
// pmsLog log1 = new pmsLog()
// {
// app = 2,
// Creationtime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")),
// Data = serializerIgnorImageForLoginfo,
// step = 4,
// message = "控制台已发送数据给人脸机," + "SN:" + Elist.msgx.sn + ",房间号:" + roomid + ",是否公区:" + (int.Parse(isgqu) == 1 ? "是" : "否"),
// pmsid = Elist.pmsid
// };
// BLL.addPmsLog(log1);
//}
//LogHelper.WriteLine("到 6");
var oks = false;
for (int i = 0; i < 6; i++)
{
//LogHelper.WriteLine("到 7发送设备前, 第" + i + "次");
var s = SendMsgToDevice(Elist.msgx.sn, serializerinfo, serializerIgnorImageForLoginfo).Result;
//LogHelper.WriteLine("到 7发送设备后, 第" + i + "次");
if (s) //第1次或者第n次发送设备成功, 则break
{
facedevicerxtxinfo logdeviceitem = new facedevicerxtxinfo()
{
pmsid = Elist.pmsid,
sn = Elist.msgx.sn,
msgid = Elist.msgx.msgid,
cmd = Elist.msgx.cmd,
data = serializerIgnorImageForLoginfo,
datatime = DateTime.Now,
direction = "Tx",
trresult = 1,
ipaddr = "",
iplocation = ""
};
SqlSugarBase.FaceDb.Insertable(logdeviceitem).ExecuteCommand();
//LogHelper.WriteLine("到 8 发送设备成功后, 第" + i + "次");
SendWebDatabase(new Entity.msgx()
{
msgid = Elist.msgx.msgid,
msg = "已成功...",
cmd = "3"
});
//LogHelper.WriteLine("到 9发送设备成功后, 第" + i + "次");
if (Elist.msgx.cmd == "removePerson")
{
BLL.getmessage(Elist.pmsid);
}
if (Elist.pmsid == -1)//Log information send down to device only for test
{
pmsLog logprevtest = new pmsLog()
{
app = 2,
Creationtime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")),
Data = serializerIgnorImageForLoginfo,
step = 501,
message = Elist.msgx.sn + "|控制台已成功发送数据到设备" + "SN:" + Elist.msgx.sn,
pmsid = 0
};
BLL.addPmsLog(logprevtest);
}
//LogHelper.WriteLine("到 10 发送设备成功后, 第" + i + "次");
oks = true;
break;
}
else //第1次或者第n次发送设备失败
{
facedevicerxtxinfo logdeviceitem1 = new facedevicerxtxinfo
{
pmsid = Elist.pmsid,
sn = Elist.msgx.sn,
msgid = Elist.msgx.msgid,
cmd = Elist.msgx.cmd,
data = serializerIgnorImageForLoginfo,
datatime = DateTime.Now,
direction = "Tx",
trresult = 0,
ipaddr = "",
iplocation = ""
};
SqlSugarBase.FaceDb.Insertable(logdeviceitem1).ExecuteCommand();
//LogHelper.WriteLine("到 11 发送设备失败后, 第" + i + "次");
Elist.msgx.msg = $"SN:{Elist.msgx.sn}重发{i}次失败~";
if (Elist.pmsid != -1)
{
pmsLog log3 = new pmsLog()
{
app = 2,
Creationtime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")),
step = 502,
message = "SN:" + Elist.msgx.sn + "重发人脸机次数" + i,
pmsid = Elist.pmsid
};
BLL.addPmsLog(log3);
}
//LogHelper.WriteLine("到 12 发送设备失败后, 第" + i + "次");
}
//10s后重发
Task.Delay(10000).Wait();
}
if (!oks)//发完60次依然失败
{
SendWebDatabase(new Entity.msgx
{
msgid = Elist.msgx.msgid,
msg = "失败," + "SN:" + Elist.msgx.sn + "重发达到最大",
cmd = "2"
});
faceerrormsg fmsg = new faceerrormsg();
devicemanage devinfo = SqlSugarBase.FaceDb.Queryable<devicemanage>().First(it => it.SerialNo == Elist.msgx.sn);
if (devinfo != null)
{
if (devinfo.Factory == "移海")
{
fmsg.brandinfo = "yh";
//fmsg.errorcode = ms.status;
//fmsg.errormsg = ms.msg;
fmsg.creationtime = DateTime.Now;
fmsg.sn = Elist.msgx.sn;
fmsg.step = 504;
fmsg.pmsid = IsLikeGuidByArr(Elist.msgx.msgid) ? -1 : int.Parse(Elist.msgx.msgid);
fmsg.remary = "已经超过了重发次数";
fmsg.APKVersion = devinfo.APKVersion;
fmsg.hotelid = devinfo.HotelCode;
fmsg.Roomid = devinfo.RoomId.ToString();
fmsg.cmd = Elist.msgx.cmd;
int d = SqlSugarBase.FaceDb.Insertable(fmsg).ExecuteCommand();
}
}
//LogHelper.WriteLine("到 13 发送设备60次失败后");
//if (Elist.pmsid != -1)
//{
// pmsLog log4 = new pmsLog()
// {
// app = 2,
// Creationtime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")),
// //step = 6,
// step = 7,
// message = "pms数据发送人脸机失败" + "SN:" + Elist.msgx.sn + ",房间号:" + roomid + ",是否公区:" + (int.Parse(isgqu) == 1 ? "是" : "否"),
// pmsid = Elist.pmsid
// };
// BLL.addPmsLog(log4);
//}
//LogHelper.WriteLine("到 14 发送设备60次失败后");
}//end of if (!ok)//发完60次依然失败
}
else
{
if (arr.Length == 12)
{
string roomid = arr[10].Split('=')[1].ToString();
string isgqu = arr[11].Split('=')[1].ToString();
//Console.WriteLine(roomid);
//Console.WriteLine(isgqu);
#region
if (Elist.pmsid != -1)
{
pmsLog log = new pmsLog()
{
app = 2,
Creationtime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")),
Data = receiveString,
step = 505,
message = "控制台已接收到数据," + "SN:" + Elist.msgx.sn + ",房间号:" + roomid + ",是否公区:" + (int.Parse(isgqu) == 1 ? "是" : "否"),
pmsid = Elist.pmsid
};
BLL.addPmsLog(log);
}
//LogHelper.WriteLine("到 2");
//client.Close();//关闭连接
//判定是接口上来的数据还是Web端
if (Elist.msgx.cmd == "setPerson")
{
string str4 = "";
string str2 = Elist.msgx.msg.Substring(Elist.msgx.msg.IndexOf("<"), Elist.msgx.msg.IndexOf(">") - Elist.msgx.msg.IndexOf("<") + 1);
int datatype = 2; //old device always use base64 of image.
int pos = -1;
string str3 = "";
pos = Elist.msgx.msg.IndexOf("&datatype=");
if (pos >= 0)
{
datatype = int.Parse(Elist.msgx.msg.Substring(pos + 10, 1));
}
if (datatype == 0)//dataype == 0; use base64 of 特征值 of image.
{
str3 = str2.Substring(str2.IndexOf("<") + 1, str2.IndexOf(">") - 1);
str4 = ImageToBase64(str3);
}
else if (datatype == 1)//datatype==1, use ftp url path
{
str3 = str2.Substring(str2.IndexOf("<") + 1, str2.IndexOf(">") - 1);
str4 = str3;
}
else //datatype == 2 ; old device or use base64 of image.
{
str3 = str2.Substring(str2.IndexOf("<") + 1, str2.IndexOf(">") - 1);
str4 = ImageToBase64(str3);
}
Elist.msgx.msg = Elist.msgx.msg.Replace(str2, str4);
NoPhotoElist.msgx.msg = NoPhotoElist.msgx.msg.Replace(str2, "PHOTO_IMAGE_AT_HERE_WITH_LENGTH_" + str4.Length);
}
else if (Elist.msgx.cmd == "setPerson)")
{
string truncate = Elist.msgx.cmd.Substring(Elist.msgx.cmd.IndexOf(")"));
Elist.msgx.cmd = Elist.msgx.cmd.Replace(truncate, "");
string str2 = Elist.msgx.msg.Substring(Elist.msgx.msg.IndexOf("<"), Elist.msgx.msg.IndexOf(">") - Elist.msgx.msg.IndexOf("<") + 1);
string str3 = str2.Substring(str2.IndexOf("<") + 1, str2.IndexOf(">") - 1);
string str4 = getFileBase64(str3);
Elist.msgx.msg = Elist.msgx.msg.Replace(str2, str4);
NoPhotoElist.msgx.msg = NoPhotoElist.msgx.msg.Replace(str2, "PHOTO_IMAGE_AT_HERE_WITH_LENGTH_" + str4.Length);
}
else if (Elist.msgx.cmd == "updateMainPageBG" || Elist.msgx.cmd == "updateLogoRoomNo")
{
string str2 = Elist.msgx.msg.Substring(Elist.msgx.msg.IndexOf("<"), Elist.msgx.msg.IndexOf(">") - Elist.msgx.msg.IndexOf("<") + 1);
string str3 = str2.Substring(str2.IndexOf("<") + 1, str2.IndexOf(">") - 1);
var set = Program.YHFileImage(str3);
//LogHelper.WriteLine("base64为" + set);
Elist.msgx.msg = Elist.msgx.msg.Replace(str2, set);
NoPhotoElist.msgx.msg = NoPhotoElist.msgx.msg.Replace(str2, "PHOTO_IMAGE_AT_HERE_WITH_LENGTH_" + set.Length);
}
//LogHelper.WriteLine("到 3");
id = Elist.msgx.msgid;
string serializerinfo = JsonConvert.SerializeObject(Elist.msgx);//对象转换josn
string serializerIgnorImageForLoginfo = JsonConvert.SerializeObject(NoPhotoElist.msgx);
pmsProcess pmsinfo = new pmsProcess()
{
messageid = id,
issuestate = 0,
receive = 1,
Issueface = 0,
cmdType = Elist.msgx.cmd
};
//BLL.pmsmemory(pms);
//发送确认
//LogHelper.WriteLine("到 4");
SendWebDatabase(new Entity.msgx
{
msgid = Elist.msgx.msgid,
cmd = "0",
msg = "已收到..."
});
SendWebDatabase(new Entity.msgx
{
msgid = Elist.msgx.msgid,
cmd = "1",
msg = "正处理..."
});
//LogHelper.WriteLine("到 5");
if (Elist.pmsid != -1)
{
pmsLog log1 = new pmsLog()
{
app = 2,
Creationtime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")),
Data = serializerIgnorImageForLoginfo,
step = 506,
message = "控制台已发送数据给人脸机," + "SN:" + Elist.msgx.sn + ",房间号:" + roomid + ",是否公区:" + (int.Parse(isgqu) == 1 ? "是" : "否"),
pmsid = Elist.pmsid
};
BLL.addPmsLog(log1);
}
//LogHelper.WriteLine("到 6");
var oks = false;
for (int i = 0; i < 6; i++)
{
//LogHelper.WriteLine("到 7发送设备前, 第" + i + "次");
var s = SendMsgToDevice(Elist.msgx.sn, serializerinfo, serializerIgnorImageForLoginfo).Result;
//LogHelper.WriteLine("到 7发送设备后, 第" + i + "次");
if (s) //第1次或者第n次发送设备成功, 则break
{
facedevicerxtxinfo logdeviceitem = new facedevicerxtxinfo()
{
pmsid = Elist.pmsid,
sn = Elist.msgx.sn,
msgid = Elist.msgx.msgid,
cmd = Elist.msgx.cmd,
data = serializerIgnorImageForLoginfo,
datatime = DateTime.Now,
direction = "Tx",
trresult = 1,
ipaddr = "",
iplocation = ""
};
SqlSugarBase.FaceDb.Insertable(logdeviceitem).ExecuteCommand();
//LogHelper.WriteLine("到 8 发送设备成功后, 第" + i + "次");
SendWebDatabase(new Entity.msgx()
{
msgid = Elist.msgx.msgid,
msg = "已成功...",
cmd = "3"
});
//LogHelper.WriteLine("到 9发送设备成功后, 第" + i + "次");
if (Elist.msgx.cmd == "removePerson")
{
BLL.getmessage(Elist.pmsid);
}
if (Elist.pmsid == -1)//Log information send down to device only for test
{
pmsLog logprevtest = new pmsLog()
{
app = 2,
Creationtime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")),
Data = serializerIgnorImageForLoginfo,
step = 501,
message = Elist.msgx.sn + "|控制台已成功发送数据到设备" + "SN:" + Elist.msgx.sn + ",房间号:" + roomid + ",是否公区:" + (int.Parse(isgqu) == 1 ? "是" : "否"),
pmsid = 0
};
BLL.addPmsLog(logprevtest);
}
//LogHelper.WriteLine("到 10 发送设备成功后, 第" + i + "次");
oks = true;
break;
}
else //第1次或者第n次发送设备失败
{
facedevicerxtxinfo logdeviceitem1 = new facedevicerxtxinfo
{
pmsid = Elist.pmsid,
sn = Elist.msgx.sn,
msgid = Elist.msgx.msgid,
cmd = Elist.msgx.cmd,
data = serializerIgnorImageForLoginfo,
datatime = DateTime.Now,
direction = "Tx",
trresult = 0,
ipaddr = "",
iplocation = ""
};
SqlSugarBase.FaceDb.Insertable(logdeviceitem1).ExecuteCommand();
//LogHelper.WriteLine("到 11 发送设备失败后, 第" + i + "次");
Elist.msgx.msg = $"SN:{Elist.msgx.sn}重发{i}次失败~";
if (Elist.pmsid != -1)
{
pmsLog log3 = new pmsLog()
{
app = 2,
Creationtime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")),
step = 508,
message = "SN:" + Elist.msgx.sn + "重发人脸机次数" + i + ",房间号:" + roomid + ",是否公区:" + (int.Parse(isgqu) == 1 ? "是" : "否"),
pmsid = Elist.pmsid
};
BLL.addPmsLog(log3);
}
//LogHelper.WriteLine("到 12 发送设备失败后, 第" + i + "次");
}
//2024-5-8修改成10s重发一次
//10s后重发
Task.Delay(10000).Wait();
}
if (!oks)//发完60次依然失败
{
SendWebDatabase(new Entity.msgx
{
msgid = Elist.msgx.msgid,
msg = "失败," + "SN:" + Elist.msgx.sn + "重发达到最大" + ",房间号:" + roomid + ",是否公区:" + (int.Parse(isgqu) == 1 ? "是" : "否"),
cmd = "2"
});
//LogHelper.WriteLine("到 13 发送设备60次失败后");
if (Elist.pmsid != -1)
{
pmsLog log4 = new pmsLog()
{
app = 2,
Creationtime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")),
//step = 6,
step = 509,
message = "pms数据发送人脸机失败" + "SN:" + Elist.msgx.sn + ",房间号:" + roomid + ",是否公区:" + (int.Parse(isgqu) == 1 ? "是" : "否"),
pmsid = Elist.pmsid
};
BLL.addPmsLog(log4);
}
faceerrormsg fmsg = new faceerrormsg();
devicemanage devinfo = SqlSugarBase.FaceDb.Queryable<devicemanage>().First(it => it.SerialNo == Elist.msgx.sn);
if (devinfo != null)
{
if (devinfo.Factory == "移海")
{
fmsg.brandinfo = "yh";
//fmsg.errorcode = ms.status;
//fmsg.errormsg = ms.msg;
fmsg.creationtime = DateTime.Now;
fmsg.sn = Elist.msgx.sn;
fmsg.step = 504;
fmsg.pmsid = IsLikeGuidByArr(Elist.msgx.msgid) ? -1 : int.Parse(Elist.msgx.msgid);
fmsg.remary = "已经超过了重发次数";
fmsg.APKVersion = devinfo.APKVersion;
fmsg.hotelid = devinfo.HotelCode;
fmsg.Roomid = devinfo.RoomId.ToString();
fmsg.cmd = Elist.msgx.cmd;
int d = SqlSugarBase.FaceDb.Insertable(fmsg).ExecuteCommand();
}
}
//LogHelper.WriteLine("到 14 发送设备60次失败后");
}//end of if (!ok)//发完60次依然失败
#endregion
}
else
{
//LogHelper.WriteLine("到 1");
#region
if (Elist.pmsid != -1)
{
pmsLog log = new pmsLog()
{
app = 2,
Creationtime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")),
Data = receiveString,
step = 520,
message = "控制台已接收到数据," + "SN:" + Elist.msgx.sn,
pmsid = Elist.pmsid
};
BLL.addPmsLog(log);
}
//LogHelper.WriteLine("到 2");
//client.Close();//关闭连接
//判定是接口上来的数据还是Web端
if (Elist.msgx.cmd == "setPerson")
{
string str4 = "";
string str2 = Elist.msgx.msg.Substring(Elist.msgx.msg.IndexOf("<"), Elist.msgx.msg.IndexOf(">") - Elist.msgx.msg.IndexOf("<") + 1);
int datatype = 2; //old device always use base64 of image.
int pos = -1;
string str3 = "";
pos = Elist.msgx.msg.IndexOf("&datatype=");
if (pos >= 0)
{
datatype = int.Parse(Elist.msgx.msg.Substring(pos + 10, 1));
}
if (datatype == 0)//dataype == 0; use base64 of 特征值 of image.
{
str3 = str2.Substring(str2.IndexOf("<") + 1, str2.IndexOf(">") - 1);
str4 = ImageToBase64(str3);
}
else if (datatype == 1)//datatype==1, use ftp url path
{
str3 = str2.Substring(str2.IndexOf("<") + 1, str2.IndexOf(">") - 1);
str4 = str3;
}
else //datatype == 2 ; old device or use base64 of image.
{
str3 = str2.Substring(str2.IndexOf("<") + 1, str2.IndexOf(">") - 1);
str4 = ImageToBase64(str3);
}
Elist.msgx.msg = Elist.msgx.msg.Replace(str2, str4);
NoPhotoElist.msgx.msg = NoPhotoElist.msgx.msg.Replace(str2, "PHOTO_IMAGE_AT_HERE_WITH_LENGTH_" + str4.Length);
}
else if (Elist.msgx.cmd == "setPerson)")
{
string truncate = Elist.msgx.cmd.Substring(Elist.msgx.cmd.IndexOf(")"));
Elist.msgx.cmd = Elist.msgx.cmd.Replace(truncate, "");
string str2 = Elist.msgx.msg.Substring(Elist.msgx.msg.IndexOf("<"), Elist.msgx.msg.IndexOf(">") - Elist.msgx.msg.IndexOf("<") + 1);
string str3 = str2.Substring(str2.IndexOf("<") + 1, str2.IndexOf(">") - 1);
string str4 = getFileBase64(str3);
Elist.msgx.msg = Elist.msgx.msg.Replace(str2, str4);
NoPhotoElist.msgx.msg = NoPhotoElist.msgx.msg.Replace(str2, "PHOTO_IMAGE_AT_HERE_WITH_LENGTH_" + str4.Length);
}
else if (Elist.msgx.cmd == "updateMainPageBG" || Elist.msgx.cmd == "updateLogoRoomNo")
{
string str2 = Elist.msgx.msg.Substring(Elist.msgx.msg.IndexOf("<"), Elist.msgx.msg.IndexOf(">") - Elist.msgx.msg.IndexOf("<") + 1);
string str3 = str2.Substring(str2.IndexOf("<") + 1, str2.IndexOf(">") - 1);
//Console.WriteLine(str3);
var set = Program.YHFileImage(str3);
//LogHelper.WriteLine("base64为" + set);
//下发内容
Elist.msgx.msg = Elist.msgx.msg.Replace(str2, set);
//日志内容
NoPhotoElist.msgx.msg = NoPhotoElist.msgx.msg.Replace(str2, "PHOTO_IMAGE_AT_HERE_WITH_LENGTH_" + set.Length);
}
//LogHelper.WriteLine("到 3");
id = Elist.msgx.msgid;
string serializer = JsonConvert.SerializeObject(Elist.msgx);//对象转换josn
string serializerIgnorImageForLog = JsonConvert.SerializeObject(NoPhotoElist.msgx);
pmsProcess pms = new pmsProcess()
{
messageid = id,
issuestate = 0,
receive = 1,
Issueface = 0,
cmdType = Elist.msgx.cmd
};
//BLL.pmsmemory(pms);
//发送确认
//LogHelper.WriteLine("到 4");
SendWebDatabase(new Entity.msgx
{
msgid = Elist.msgx.msgid,
cmd = "0",
msg = "已收到..."
});
SendWebDatabase(new Entity.msgx
{
msgid = Elist.msgx.msgid,
cmd = "1",
msg = "正处理..."
});
//LogHelper.WriteLine("到 5");
if (Elist.pmsid != -1)
{
pmsLog log1 = new pmsLog()
{
app = 2,
Creationtime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")),
Data = serializerIgnorImageForLog,
step = 521,
message = "控制台已发送数据给人脸机," + "SN:" + Elist.msgx.sn,
pmsid = Elist.pmsid
};
BLL.addPmsLog(log1);
}
//LogHelper.WriteLine("到 6");
var ok = false;
for (int i = 0; i < 6; i++)
{
//LogHelper.WriteLine("到 7发送设备前, 第" + i + "次");
var s = SendMsgToDevice(Elist.msgx.sn, serializer, serializerIgnorImageForLog).Result;
//LogHelper.WriteLine("到 7发送设备后, 第" + i + "次");
if (s) //第1次或者第n次发送设备成功, 则break
{
facedevicerxtxinfo logdeviceitem = new facedevicerxtxinfo()
{
pmsid = Elist.pmsid,
sn = Elist.msgx.sn,
msgid = Elist.msgx.msgid,
cmd = Elist.msgx.cmd,
data = serializerIgnorImageForLog,
datatime = DateTime.Now,
direction = "Tx",
trresult = 1,
ipaddr = "",
iplocation = ""
};
SqlSugarBase.FaceDb.Insertable(logdeviceitem).ExecuteCommand();
//LogHelper.WriteLine("到 8 发送设备成功后, 第" + i + "次");
SendWebDatabase(new Entity.msgx()
{
msgid = Elist.msgx.msgid,
msg = "已成功...",
cmd = "3"
});
//LogHelper.WriteLine("到 9发送设备成功后, 第" + i + "次");
if (Elist.msgx.cmd == "removePerson")
{
BLL.getmessage(Elist.pmsid);
}
if (Elist.pmsid == -1)//Log information send down to device only for test
{
pmsLog logprevtest = new pmsLog()
{
app = 2,
Creationtime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")),
Data = serializerIgnorImageForLog,
step = 501,
message = Elist.msgx.sn + "|控制台已成功发送数据到设备" + "SN:" + Elist.msgx.sn,
pmsid = 0
};
BLL.addPmsLog(logprevtest);
}
//LogHelper.WriteLine("到 10 发送设备成功后, 第" + i + "次");
ok = true;
break;
}
else //第1次或者第n次发送设备失败
{
facedevicerxtxinfo logdeviceitem1 = new facedevicerxtxinfo
{
pmsid = Elist.pmsid,
sn = Elist.msgx.sn,
msgid = Elist.msgx.msgid,
cmd = Elist.msgx.cmd,
data = serializerIgnorImageForLog,
datatime = DateTime.Now,
direction = "Tx",
trresult = 0,
ipaddr = "",
iplocation = ""
};
SqlSugarBase.FaceDb.Insertable(logdeviceitem1).ExecuteCommand();
//LogHelper.WriteLine("到 11 发送设备失败后, 第" + i + "次");
Elist.msgx.msg = $"SN:{Elist.msgx.sn}重发{i}次失败~";
if (Elist.pmsid != -1)
{
pmsLog log3 = new pmsLog()
{
app = 2,
Creationtime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")),
step = 502,
message = "SN:" + Elist.msgx.sn + "重发人脸机次数" + i,
pmsid = Elist.pmsid
};
BLL.addPmsLog(log3);
}
//LogHelper.WriteLine("到 12 发送设备失败后, 第" + i + "次");
}
//2024-5-8修改成10s重发一次
//10s后重发
Task.Delay(10000).Wait();
}
if (!ok)//发完60次依然失败
{
SendWebDatabase(new Entity.msgx
{
msgid = Elist.msgx.msgid,
msg = "失败," + "SN:" + Elist.msgx.sn + "重发达到最大",
cmd = "2"
});
//LogHelper.WriteLine("到 13 发送设备60次失败后");
if (Elist.pmsid != -1)
{
pmsLog log4 = new pmsLog()
{
app = 2,
Creationtime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")),
//step = 6,
step = 509,
message = "pms数据发送人脸机失败" + "SN:" + Elist.msgx.sn,
pmsid = Elist.pmsid
};
BLL.addPmsLog(log4);
}
faceerrormsg fmsg = new faceerrormsg();
devicemanage devinfo = SqlSugarBase.FaceDb.Queryable<devicemanage>().First(it => it.SerialNo == Elist.msgx.sn);
if (devinfo != null)
{
if (devinfo.Factory == "移海")
{
fmsg.brandinfo = "yh";
//fmsg.errorcode = ms.status;
//fmsg.errormsg = ms.msg;
fmsg.creationtime = DateTime.Now;
fmsg.sn = Elist.msgx.sn;
fmsg.step = 504;
fmsg.pmsid = IsLikeGuidByArr(Elist.msgx.msgid) ? -1 : int.Parse(Elist.msgx.msgid);
fmsg.remary = "已经超过了重发次数";
fmsg.APKVersion = devinfo.APKVersion;
fmsg.hotelid = devinfo.HotelCode;
fmsg.Roomid = devinfo.RoomId.ToString();
fmsg.cmd = Elist.msgx.cmd;
int d = SqlSugarBase.FaceDb.Insertable(fmsg).ExecuteCommand();
}
}
//LogHelper.WriteLine("到 14 发送设备60次失败后");
}//end of if (!ok)//发完60次依然失败
#endregion
//LogHelper.WriteLine("到 15 全部处理完毕");
}
}
//LogHelper.WriteLine(receiveString);
}
public static void SendWebDatabase(Entity.msgx Elist)
{
try
{
using (var dr = SqlSugarBase.FaceDbClient())
{
transferFace sx = dr.Queryable<transferFace>().First(x => x.infoid == Elist.msgid);
if (sx != null)
sx.faultState = int.Parse(Elist.cmd);
FaceIssue issue = dr.Queryable<FaceIssue>().First(x => x.messageid == Elist.msgid);
if (issue != null && Elist.cmd == "2")
{
issue.issuestate = 2;
var assed = dr.Queryable<devicemanage>().First(x => x.SerialNo == sx.faceSN);
SqlSugarBase.FaceDb.Updateable<devicemanage>().SetColumns(it => it.maintainStatus == 1).Where(it => it.SerialNo == sx.faceSN).ExecuteCommand();
SqlSugarBase.FaceDb.Updateable<FaceIssue>().SetColumns(it => it.issuestate == 2).Where(x => x.messageid == Elist.msgid).ExecuteCommand();
}
SqlSugarBase.FaceDb.Updateable<transferFace>().SetColumns(it => it.faultState == int.Parse(Elist.cmd)).Where(x => x.infoid == Elist.msgid).ExecuteCommand();
}
}
catch (Exception ex)
{
LogHelper.WriteLine("函数SendWebDatabase()访问transerface,faceissue,devicemanage异常: " + ex.ToString());
}
}
public static void SetAllStatusToInactive()
{
try
{
string sqlBackTable = "DROP TABLE IF EXISTS devicemanage_bak; ";
sqlBackTable += "CREATE TABLE devicemanage_bak SELECT * FROM devicemanage; ";
SqlSugarBase.FaceDb.Ado.ExecuteCommand(sqlBackTable);
SqlSugarBase.FaceDb.Updateable<devicemanage>().SetColumns(it => it.Status == false).Where(it => 1 == 1).ExecuteCommand();
}
catch (Exception ex)
{
LogHelper.WriteLine("函数SetAllStatusToInactive()清除所有设备的初始状态异常: " + ex.ToString());
}
}
/// <summary>
/// 统计ping周期写入数据库
/// </summary>
/// <param name="objTmp"></param>
public static void WritePingStatusToDB(object objTmp)
{
LogHelper.Write("事件:ping周期统计。链路个数" + pingLinkNum + "。\r\n");
int i = 0;
string strPathKey = "";
int strCntVal = -1;
string strTestOut = "";
for (i = 0; i < pingLinkNum; i++)
{
lock (pingCount[i])
{
SocketCount curItem = pingCount[i];
strPathKey = curItem.path;
strCntVal = curItem.count;
pingCount[i].count = 0;
}// end of lock (pingCount[i])
//一定会有,这两个是同时初始化的。
//if(!_dicSocketsPingLastStat.ContainsKey(strPathKey))
//{
// continue;
//}
strTestOut = "";
if (strCntVal >= pingCountLowValue && !_dicSocketsPingLastStat[strPathKey]) //is still active
{
strTestOut += "处理第" + (i + 1) + "条链路:'" + strPathKey + "'。" + "收到Ping次数" + strCntVal + "。";
strTestOut += "触发状态反转:从死到活。";
strTestOut += "\r\n";
FactoryAndSn fands = extractSN(strPathKey);
//update to history log table, update to device table
InsertHistoryLog(fands.sn, fands.factory, true, "Ping周期采样状态反转触发");
_dicSocketsPingLastStat[strPathKey] = true;
UpdateDeviceLivingStatus(fands.sn, true);
}
else if (strCntVal < pingCountLowValue && _dicSocketsPingLastStat[strPathKey])//is low active, or maybe dead.
{
strTestOut += "处理第" + (i + 1) + "条链路:'" + strPathKey + "'。" + "收到Ping次数" + strCntVal + "。";
strTestOut += "触发状态反转:从活到死。";
strTestOut += "\r\n";
FactoryAndSn fands1 = extractSN(strPathKey);
//update to history log table, update to device table
InsertHistoryLog(fands1.sn, fands1.factory, false, "Ping周期采样状态反转触发");
_dicSocketsPingLastStat[strPathKey] = false;
UpdateDeviceLivingStatus(fands1.sn, false);
}
}// end of for(i = 0; i < pingLinkNum; i ++)
if (!String.IsNullOrEmpty(strTestOut))
LogHelper.Write(strTestOut);
}
//public class
// GET: Default
/// <summary>
/// Websocket服务
/// </summary>
public static void Index()
{
int i = 0;
NoProcessSN = new List<string>();
//1分钟1次onerror
NoProcessSN.Add("717582042B8F443A");
NoProcessSN.Add("11EA322437F396B4");
//NoProcessSN.Add("E8AB3597C832F79C");
//NoProcessSN.Add("52B2A330DAD13749");
FleckLog.Level = LogLevel.Debug;
// var allSockets = new List<IWebSocketConnection>();
var server = new WebSocketServer("ws://0.0.0.0:82");
server.RestartAfterListenError = true;//出错后进行重启
_dicSockets = new Dictionary<String, IWebSocketConnection>();
_dicSocketsPingLastStat = new Dictionary<string, bool>();
LogHelper.Write("启动 web socket服务器之前初始化字典对象 pingCount 为 4098 个类型为SocketCount的默认值对象。\r\n");
server.Start(socket =>
{
//这个回调函数被执行前已经收到了客户端的Accept返回的socket并且解析了ws协议
//这个回调函数的参数socket 是一个 WebSocketConnection 类型的实例
//内部重要属性有:
/* Socket 是一个SocketWrapper类型的实例里面有一个链路socket, 所以可以认为这个实例是一个链路的socket
* ConnectionInfo
*/
//这个回调函数被执行后,发送握手包到客户端。
//发送握手包的stream write end成功之后调用onOpen回调
//没有串号的设备不符合协议,不做任何记录,不做任何处理。本地测试注释掉
if (String.IsNullOrWhiteSpace(extractSN(socket.ConnectionInfo.Path).sn))
{
socket.OnOpen = () => { };
socket.OnPing = bytes => { };
socket.OnMessage = message => { };
socket.OnError = exception => { };
socket.OnClose = () => { };
return;
}
//指定黑名单的设备,不做任何记录,不做任何处理,不做任何响应。本地测试注释掉
if (NoProcessSN.Contains(extractSN(socket.ConnectionInfo.Path).sn))
{
socket.OnOpen = () => { };
socket.OnPing = bytes => { };
socket.OnMessage = message => { };
socket.OnError = exception => { };
socket.OnClose = () => { };
return;
}
string serialNo = "", factory = "未知厂家", ip = "";
socket.OnOpen = () =>
{
if (!socket.IsAvailable)
{
return;
}
ip = socket.ConnectionInfo.ClientIpAddress;//获取ip地址
FactoryAndSn facandsn = extractSN(socket.ConnectionInfo.Path);
factory = facandsn.factory;
serialNo = facandsn.sn;
try
{
/*
* 第一次
* 四个集合建立的时候要表级别锁,因为建立的时候会移动位置,多线程抢入可能使用错误位置。
* 链路字典
* ping统计数组
* ping工具数组的反向索引字典
* 最新链路状态字典
*
*
* 第 n 次
* 后续更新
* 链路字典任然需要表级别锁。
* ping相关的两个集合都不需要锁但是难以分离逻辑。使用if(!xxx)逻辑快速跳过
*/
int matchedPos = -1;
bool firstCreateStat = false;
lock (dicSocksLock)
{
//1. 链路字典。 字典增加item时内部实现也是要更新插入位置插入对象多线程并行执行会导致位置放错
//这里简化第一次第n次都锁。
_dicSockets[serialNo] = socket;
//2. ping统计信息
//ping统计信息数组第一次建立时处理位置信息和对象时不能多线程并行执行。
//ping统计信息数组的反向索引表第一次建立时也不能多线程并行执行。
matchedPos = -1;
if (reverseDic.Count > 0 && reverseDic.ContainsKey(socket.ConnectionInfo.Path))
{
matchedPos = reverseDic[socket.ConnectionInfo.Path];
}
if (matchedPos < 0)//第一次连接,建立所有链路的ping统计数组不能多线程并行执行
{
pingCount[pingLinkNum] = new SocketCount
{
path = socket.ConnectionInfo.Path,
count = 0
};
reverseDic.Add(socket.ConnectionInfo.Path, pingLinkNum);
pingLinkNum++;
}
//3. 最近状态字典。第一次建立所有链路的最近状态集合时,也不能多线程并行执行。
//第一次时加item并设置为true
//第n次时由ping统计计数来更新
if (!_dicSocketsPingLastStat.ContainsKey(socket.ConnectionInfo.Path))
{
firstCreateStat = true;
_dicSocketsPingLastStat.Add(socket.ConnectionInfo.Path, true);
}
//Add 和 Update都设置为true
_dicSocketsPingLastStat[socket.ConnectionInfo.Path] = true;
}
//简化逻辑后续重新建立链路不再影响ping统计计数。
//所有上线事件写上线日志记录,并区分第一次建立链路,还是后续重新建立链路。
InsertHistoryLog(serialNo, factory, true, (firstCreateStat ? "链路第一次OnOpen触发" : "链路重新OnOpen触发"));
//BLL.SaveDevice(serialNo, factory, ip, location); //将人脸机数据添加到数据库
//if(firstCreateStat)
//{
// string location = GetBaiduIp(ip);
// InsertDeviceLivingStatus(serialNo, factory, ip, location, true);//将人脸机数据添加到数据库
//}
//else
//{
// UpdateDeviceLivingStatus(serialNo, true);
//}
InsertOrUpdateDeviceLivingStatus(serialNo, factory, ip, true);
}
catch (Exception ex)
{
LogHelper.WriteLine("控制台与人脸机设备" + ip + "建立连接后,创建内部数据字典,获取连接路径(人脸机串号),将串号加入数据库时出错。 " + ex.Message);
}
};
socket.OnPing = bytes =>
{
//ping因为很频繁不try不记文本日志不记数据库日志。
//回复pong格式包。不过历史原因依然保留pong字符串。
string oldPongString = "pong";
socket.SendPong(Encoding.UTF8.GetBytes(oldPongString));
int matchedPos1 = -1;
if (reverseDic.Count > 0 && reverseDic.ContainsKey(socket.ConnectionInfo.Path))
{
matchedPos1 = reverseDic[socket.ConnectionInfo.Path];
}
if (matchedPos1 >= 0)
{
lock (pingCount[matchedPos1])
{
pingCount[matchedPos1].count++;
}
}
};
socket.OnMessage = message =>//接收数据
{
LogHelper.Write("xxxxx" + JsonConvert.SerializeObject(message));
try
{
//收到消息则pingpong计数可以加1
int matchedPos2 = -1;
if (reverseDic.Count > 0 && reverseDic.ContainsKey(socket.ConnectionInfo.Path))
{
matchedPos2 = reverseDic[socket.ConnectionInfo.Path];
}
if (matchedPos2 >= 0)
{
lock (pingCount[matchedPos2])
{
(pingCount[matchedPos2].count)++;
}
}
//两种格式注意msg里面一种是字符串一种是对象
//{"msgid":"5a671c4b-bf1d-4cfd-ac0b-76ade09de40a","sn":"11E8C6B16D7A0DE2","cmd":"open","msg":"{\"status\":0,\"msg\":\"成功\"}"}
//{"msgid":"197529","sn":"41437ccd65dadcc1","cmd":"","msg":{"status":0,"msg":"OK"}}
//LogHelper.Write("设备上报消息:" + message);
//LogHelper.Write("设备上报消息:" + message + "\r\n" + "事件收到设备端Ping事件。链路" + socket.ConnectionInfo.Path + "。Ping统计信息" + _dicSocketsPingCount[socket.ConnectionInfo.Path]);
//socket.Send("pong");
///string oldPongString = "pong";
//socket.SendPong(Encoding.UTF8.GetBytes(oldPongString));
i++;
//Entity.msgxs Elist = JsonConvert.DeserializeObject<Entity.msgxs>(message);//josn转换实体类
//Entity.msgx Elist = JsonConvert.DeserializeObject<Entity.msgx>(message);//josn转换实体类
Entity.msgx itmsg = new Entity.msgx();
string[] sepArr = { "\"msgid\":", "\"sn\":", "\"cmd\":", "\"msg\":{", "\"msg\":\"{" };
string[] msgItemArr = message.Split(sepArr, StringSplitOptions.RemoveEmptyEntries);
itmsg.msgid = msgItemArr[1].Substring(1, msgItemArr[1].Length - 3);
itmsg.sn = msgItemArr[2].Substring(1, msgItemArr[2].Length - 3);
itmsg.cmd = msgItemArr[3].Substring(1, msgItemArr[3].Length - 3);//"open",
// 20250508修改添加json解析 XU
ToWebFaceinfo faceinfo = JsonConvert.DeserializeObject<ToWebFaceinfo>(message);
try
{
if (itmsg.cmd == "getDeviceInfo")
{
cmdinfo info = JsonConvert.DeserializeObject<Entity.cmdinfo>(message);
List<FaceIssue> pmsinfosd = SqlSugarBase.FaceDb.Queryable<FaceIssue>().Where(it => it.faceSn == info.sn).ToList();
for (int x = 0; x < pmsinfosd.Count(); x++)
{
FaceIssue sd = new FaceIssue();
sd.id = pmsinfosd[x].id;
if (factory == "移海")
{
sd.Factory = "yh";
}
else if (factory == "实义德")
{
sd.Factory = "devs";
}
else if (factory == "深圳嘉禾兴")
{
sd.Factory = "szjhx";
}
else
{
sd.Factory = " ";
}
int d = SqlSugarBase.FaceDb.Updateable(sd).UpdateColumns(b => new { b.Factory }).Where(b => b.id == sd.id).ExecuteCommand();
//arr.Add(sd);
}
if (info.msg.data.APKVersion != null)
{
//List<FaceIssue> pmsinfo = SqlSugarBase.FaceDb.Queryable<FaceIssue>().Where(it => it.faceSn == info.msg.data.sn).ToList();
devicemanage devinfo = SqlSugarBase.FaceDb.Queryable<devicemanage>().First(it => it.SerialNo == info.msg.data.sn);
devinfo.APKVersion = info.msg.data.APKVersion;
int s = SqlSugarBase.FaceDb.Updateable(devinfo).Where(x => x.SerialNo == info.msg.data.sn).ExecuteCommand();
for (int x = 0; x < pmsinfosd.Count(); x++)
{
FaceIssue sd = new FaceIssue();
sd.id = pmsinfosd[x].id;
sd.APKVersion = info.msg.data.APKVersion;
int d = SqlSugarBase.FaceDb.Updateable(sd).UpdateColumns(b => new { b.APKVersion }).Where(b => b.id == sd.id).ExecuteCommand();
}
}
else
{
//List<FaceIssue> pmsinfo = SqlSugarBase.FaceDb.Queryable<FaceIssue>().Where(it => it.faceSn == info.sn).ToList();
devicemanage devinfo = SqlSugarBase.FaceDb.Queryable<devicemanage>().First(it => it.SerialNo == info.sn);
devinfo.APKVersion = " ";
int s = SqlSugarBase.FaceDb.Updateable(devinfo).Where(x => x.SerialNo == info.sn).ExecuteCommand();
for (int x = 0; x < pmsinfosd.Count(); x++)
{
FaceIssue sd = new FaceIssue();
sd.id = pmsinfosd[x].id;
sd.APKVersion = " ";
int d = SqlSugarBase.FaceDb.Updateable(sd).UpdateColumns(b => new { b.APKVersion }).Where(b => b.id == sd.id).ExecuteCommand();
}
}
}
else if (itmsg.cmd == "GetModelInfo")
{
Facereturuhandlingmethod(message, itmsg.msgid);
}
else if (itmsg.cmd == "SetUI")
{
//Faceinfos<T> fs = JsonConvert.DeserializeObject<Faceinfos<T>>(message);
}
else if (itmsg.cmd == "RestoreFactorySetting")
{
Facereturuhandlingmethod(message, itmsg.msgid);
}
else if (itmsg.cmd == "UpdateApk2")
{
Facereturuhandlingmethod(message, itmsg.msgid);
}
else if (itmsg.cmd == "UploadLogData")
{
Facereturuhandlingmethod(message, itmsg.msgid);
}
else if (faceinfo.cmd == "FaceRecognized") // 2025.5.8新增
{
// LogHelper.Write("FaceRecognized" + JsonConvert.SerializeObject(faceinfo));
var rt = QueueSend(message);
var assck = _dicSockets[faceinfo.sn];
devicemanage sinfo = SqlSugarBase.FaceDb.Queryable<devicemanage>().First(it => it.SerialNo == faceinfo.sn);
using (var client = new HttpClient())
{
var parameters = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("HotelId",faceinfo.msg.Para.HotelID),
new KeyValuePair<string, string>("RoomId", faceinfo.msg.Para.RoomID),
});
var parameterstest = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("HotelId","841"),
new KeyValuePair<string, string>("RoomId","38555"),
});
var response = client.PostAsync("https://www.boonlive-rcu.com/api/QueryFaceInfo", parameters).Result;
var typeName = response.Content.ReadAsStringAsync().Result;
FaceRoomType tnv = JsonConvert.DeserializeObject<FaceRoomType>(typeName);
if (tnv.RoomTypeName == "餐厅" || tnv.RoomTypeName == "中餐厅" || tnv.RoomTypeName == "西餐厅" || tnv.RoomTypeName == "早餐厅")
{
WebToSocketErrMsg asmsg = new WebToSocketErrMsg
{
Token = "Boonlive JSON command system",
ProtocolVersion = "2.1",
MsgID = itmsg.msgid,
DateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"),
Brand = sinfo.Factory,
SN = itmsg.sn,
CMD = itmsg.cmd,
};
if (rt == "Succeed push msg to MQ !")
{
asmsg.Para = new ParaClass
{
ErrCode = 0,
ErrMsg = "OK"
};
}
else
{
asmsg.Para = new ParaClass
{
ErrCode = -1,
ErrMsg = rt
};
}
assck.Send(JsonConvert.SerializeObject(asmsg));
}
}
}
else
{
#region
FaceReturuinfo finfo = JsonConvert.DeserializeObject<FaceReturuinfo>(message);
faceerrormsg fmsg = new faceerrormsg();
devicemanage devinfo = SqlSugarBase.FaceDb.Queryable<devicemanage>().First(it => it.SerialNo == finfo.sn);
if (devinfo != null)
{
if (devinfo.Factory == "移海")
{
//magsinfo ms = JsonConvert.DeserializeObject<magsinfo>(finfo.msg);
var dg = JsonConvert.DeserializeObject<object>(message);
if (finfo.msg.status != 0)
{
fmsg.brandinfo = "yh";
fmsg.errorcode = finfo.msg.status;
fmsg.errormsg = finfo.msg.msg;
fmsg.creationtime = DateTime.Now;
fmsg.sn = finfo.sn;
fmsg.step = 514;
fmsg.pmsid = IsLikeGuidByArr(itmsg.msgid) ? -1 : int.Parse(itmsg.msgid);
fmsg.remary = "人脸机回复失败信息";
fmsg.APKVersion = devinfo.APKVersion;
fmsg.hotelid = devinfo.HotelCode;
fmsg.Roomid = devinfo.RoomId.ToString();
fmsg.cmd = itmsg.cmd;
int d = SqlSugarBase.FaceDb.Insertable(fmsg).ExecuteCommand();
}
}
}
#endregion
}
}
catch (Exception e)
{
LogHelper.Write("控制台收到人脸机信息,处理命令时异常: " + e.Message + " 收到设备端上报的内容:" + message);
//throw;
}
//To ourself log database.
facedevicerxtxinfo logdeviceitem2 = new facedevicerxtxinfo
{
pmsid = IsLikeGuidByArr(itmsg.msgid) ? -1 : int.Parse(itmsg.msgid), //guid is from test, int id from pmsid, so maybe guid should not add pms log
sn = itmsg.sn,
msgid = itmsg.msgid,
cmd = itmsg.cmd,
data = message,
datatime = DateTime.Now,
direction = "Rx",
trresult = 0,
ipaddr = "",
iplocation = ""
};
SqlSugarBase.FaceDb.Insertable(logdeviceitem2).ExecuteCommand();
//"{\"status\":0,\"msg\":\"成功\"}"}
//{\"status\":0,\"msg\":\"成功\"}}
//{\"status\":0,\"msg\":\"成功\"}}
//null}
Entity.Msg twoFormatJson = new Entity.Msg();
twoFormatJson.status = 0;
twoFormatJson.msg = "";
string strTmp = msgItemArr[4].Replace("\\\"", "\""); //去除多余的反斜杠
strTmp = strTmp.Replace("}\"}", "}}"); //去除后面多余的双引号前面的已经在split里面去掉了。
strTmp = "{" + strTmp.Substring(0, strTmp.Length - 1); // 大括号配对。
//LogHelper.Write("控制台收到人脸机信息4: " + strTmp);
if (!strTmp.Contains("null")) //not msg:{null}
{
twoFormatJson = JsonConvert.DeserializeObject<Entity.Msg>(strTmp);//josn转换实体类
}
//LogHelper.Write("控制台收到人脸机信息5 ");
pmsLog log = new pmsLog()
{
app = 2,
Creationtime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")),
step = 550,
Data = message,
message = IsLikeGuidByArr(itmsg.msgid) ? itmsg.sn + "|人脸机" + itmsg.sn + "已回复" : "人脸机" + itmsg.sn + "已回复",
pmsid = IsLikeGuidByArr(itmsg.msgid) ? -1 : int.Parse(itmsg.msgid) //guid is from test, int id from pmsid, so maybe guid should not add pms log
};
BLL.addPmsLog(log);
if (twoFormatJson.status == 0)
{
pmsLog log2 = new pmsLog()
{
app = 2,
Creationtime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")),
step = 551,
message = IsLikeGuidByArr(itmsg.msgid) ? itmsg.sn + "|人脸机" + itmsg.sn + "已处理成功" : "人脸机" + itmsg.sn + "已处理成功",
pmsid = IsLikeGuidByArr(itmsg.msgid) ? -1 : int.Parse(itmsg.msgid) //guid is from test, int id from pmsid, so maybe guid should not add pms log
};
BLL.addPmsLog(log2);
}
else
{
pmsLog log3 = new pmsLog()
{
app = 2,
Creationtime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")),
step = 540,
message = IsLikeGuidByArr(itmsg.msgid) ? itmsg.sn + "|人脸机" + itmsg.sn + "处理失败" : "人脸机" + itmsg.sn + "处理失败",
pmsid = IsLikeGuidByArr(itmsg.msgid) ? -1 : int.Parse(itmsg.msgid) //guid is from test, int id from pmsid, so maybe guid should not add pms log
};
BLL.addPmsLog(log3);
}
}
catch (Exception e)
{
LogHelper.Write("控制台收到人脸机信息,处理时异常: " + e.Message + " 收到设备端上报的内容:" + message);
}
};
socket.OnError = exception =>
{
string sktInfo = "";
sktInfo += "设备端IP地址" + socket.ConnectionInfo.ClientIpAddress;
sktInfo += " 设备端端口号:" + socket.ConnectionInfo.ClientPort;
sktInfo += " 设备端请求路径:" + socket.ConnectionInfo.Path;
sktInfo += " 设备端请求主机:" + socket.ConnectionInfo.Host;
sktInfo += " 设备端请求来源:" + socket.ConnectionInfo.Origin;
sktInfo += " 使用子协议: " + socket.ConnectionInfo.SubProtocol + " 协商子协议:" + socket.ConnectionInfo.NegotiatedSubProtocol;
try
{
//链路错误则pingpong计数清零
int matchedPos3 = -1;
if (reverseDic.Count > 0 && reverseDic.ContainsKey(socket.ConnectionInfo.Path))
{
matchedPos3 = reverseDic[socket.ConnectionInfo.Path];
}
if (matchedPos3 >= 0)
{
lock (pingCount[matchedPos3])
{
pingCount[matchedPos3].count = 0;
if (_dicSocketsPingLastStat.ContainsKey(socket.ConnectionInfo.Path))//可能第一次来error事件所以字典里面可能没有创建条目。
_dicSocketsPingLastStat[socket.ConnectionInfo.Path] = false;
}
}
//链路错误事件要更新设备最后一次状态,要更新到历史记录表。
FactoryAndSn facandsnTmp2 = extractSN(socket.ConnectionInfo.Path);
InsertHistoryLog(facandsnTmp2.sn, facandsnTmp2.factory, false, "链路OnError触发");
}
catch (Exception ex)
{
LogHelper.WriteLine("时间:" + DateTime.Now + "内容:OnError处理时异常。 链路信息:" + sktInfo + "。 异常:" + ex.ToString());
}
};
socket.OnClose = () =>
{
try
{
//链路关闭则pingpong计数清零
FactoryAndSn facandsnTmp3 = extractSN(socket.ConnectionInfo.Path);
int matchedPos4 = -1;
if (reverseDic.Count > 0 && reverseDic.ContainsKey(socket.ConnectionInfo.Path))
{
matchedPos4 = reverseDic[socket.ConnectionInfo.Path];
}
if (matchedPos4 >= 0)
{
lock (pingCount[matchedPos4])
{
pingCount[matchedPos4].count = 0;
}
}
lock (dicSocksLock)//close 和 open 抢dictionary
{
if (_dicSocketsPingLastStat.ContainsKey(socket.ConnectionInfo.Path))//可能第一次来close事件所以字典里面可能没有创建条目。
_dicSocketsPingLastStat[socket.ConnectionInfo.Path] = false;
//释放链路对象
if (_dicSockets.ContainsKey(facandsnTmp3.sn))//可能第一次来close事件所以字典里面可能没有创建条目。
_dicSockets[facandsnTmp3.sn] = null;//要释放对象,要不然就进入了死循环?结束服务?
}
//链路关闭事件要更新设备最后一次状态,要更新到历史记录表。
InsertHistoryLog(facandsnTmp3.sn, facandsnTmp3.factory, false, "链路OnClose触发");
//链路关闭肯定是更新状态到掉线。
//UpdateDeviceLivingStatus(facandsnTmp3.sn, false);
InsertOrUpdateDeviceLivingStatus(facandsnTmp3.sn, facandsnTmp3.factory, socket.ConnectionInfo.ClientIpAddress, false);
}
catch (Exception ex)
{
LogHelper.WriteLine("时间:" + DateTime.Now + "内容:OnClose处理时异常。 链路:" + socket.ConnectionInfo.Path + "。 异常:" + ex.ToString());
}
};
});
}
private static FactoryAndSn extractSN(string strPath)
{
FactoryAndSn retObj = new FactoryAndSn();
retObj.factory = "未知厂家";
retObj.sn = "";
if (String.IsNullOrWhiteSpace(strPath))
return retObj;
if (strPath.Length < 12)//串号至少16位出现过没有串号的情况 /devs/
return retObj;
if (strPath.StartsWith("/devs/"))//深圳实义德注册:/devs/514F9589072575A4
{
retObj.factory = "实义德";
retObj.sn = strPath.Substring(6);
}
else if (strPath.StartsWith("/szjhx/"))//深圳嘉禾兴注册:/szjhx/12位mac地址
{
retObj.sn = strPath.Substring(6);
}
else if (strPath.StartsWith("/yh/"))
{
retObj.factory = "移海";
retObj.sn = strPath.Substring(4);
}
return retObj;
}
/// <summary>
/// 插入历史状态数据库日志
/// </summary>
/// <param name="strSN"></param>
/// <param name="strFactory"></param>
/// <param name="beLive"></param>
/// <param name="strReason"></param>
private static void InsertHistoryLog(string strSN, string strFactory, bool beLive, string strReason = "")
{
try
{
devicestatushistory log = new devicestatushistory
{
SN = strSN,
Factory = strFactory,
Status = beLive ? 1 : 0,
CreateTime = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")),
Reason = strReason
};
SqlSugarBase.FaceDb.Insertable(log).ExecuteCommand();
/*if(strReason == "Ping周期采样状态反转触发")
{
List<devicemanage> selDeviceList = SqlSugarBase.FaceDb.Queryable<devicemanage>().Where(t => t.SerialNo == strSN).ToList();
if (selDeviceList.Count > 0)
{
SqlSugarBase.FaceDb.Tracking(selDeviceList[0]);//创建跟踪
selDeviceList[0].Status = beLive;
SqlSugarBase.FaceDb.Updateable(selDeviceList[0]).ExecuteCommand();
}
}*/
}
catch (Exception ex)
{
LogHelper.WriteLine("时间:" + DateTime.Now + "内容:插入历史状态数据库异常。数据详情SN:" + strSN + " Status:" + beLive + " Reason:" + strReason + " 异常:" + ex.ToString());
}
}
/// <summary>
/// 更新设备在线状态
/// </summary>
/// <param name="strSN"></param>
/// <param name="beLive"></param>
private static void UpdateDeviceLivingStatus(string strSN, bool beLive)
{
// 只有数据库有,才更新
List<devicemanage> selDeviceList = SqlSugarBase.FaceDb.Queryable<devicemanage>().Where(t => t.SerialNo == strSN).ToList();
if (selDeviceList.Count > 0)
{
SqlSugarBase.FaceDb.Tracking(selDeviceList[0]);//创建跟踪
selDeviceList[0].Status = beLive;
SqlSugarBase.FaceDb.Updateable(selDeviceList[0]).ExecuteCommand();
}
}
/// <summary>
/// 插入或更新设备在线状态
/// </summary>
/// <param name="strSN"></param>
/// <param name="strFactory"></param>
/// <param name="strIp"></param>
/// <param name="beLive"></param>
private static void InsertOrUpdateDeviceLivingStatus(string strSN, string strFactory, string strIp, bool beLive)
{
// 只有数据库没有,才添加。
List<devicemanage> selDeviceList = SqlSugarBase.FaceDb.Queryable<devicemanage>().Where(t => t.SerialNo == strSN).ToList();
if (selDeviceList.Count <= 0)
{
var tmpObj = new devicemanage
{
SerialNo = strSN,
CreatedDate = DateTime.Now,
Factory = strFactory,
Status = beLive,
bindingStatus = true,
faceIp = strIp,
faceAddress = GetBaiduIp(strIp),
maintainStatus = 0
};
SqlSugarBase.FaceDb.Insertable(tmpObj).ExecuteCommand();
}
else
{
SqlSugarBase.FaceDb.Tracking(selDeviceList[0]);//创建跟踪
selDeviceList[0].Status = beLive;
selDeviceList[0].Factory = strFactory; //移海要换请求url数据库这里要重新填厂商名字。
SqlSugarBase.FaceDb.Updateable(selDeviceList[0]).ExecuteCommand();
}
}
/// <summary>
/// 发信息给人脸机
/// </summary>
/// <param name="serialNo"></param>
/// <param name="sendMsg"></param>
public static async Task<bool> SendMsgToDevice(string serialNo, string sendMsg, string shortSendMsgForLog)
{
try
{
LogHelper.WriteLine("人脸机SN" + serialNo + ",信息内容:" + shortSendMsgForLog);
if (_dicSockets.ContainsKey(serialNo) && _dicSockets[serialNo] != null)
{
await _dicSockets[serialNo].Send(sendMsg);
return true;
}
else
{
LogHelper.WriteLine("人脸机SN" + serialNo + ",没有设备链路可用。");
return false;
}
}
catch (Exception ex)
{
LogHelper.WriteLine("控制台下发信息到人脸机异常:" + ex.Message);
return false;
}
}
/// <summary>
/// 图片转换base64
/// </summary>
/// <param name="图片名字"></param>
/// <returns></returns>
public static string getFileBase64(string fileName)
{
byte[] arr = FileImage(fileName);
var d = string.Format("data:image/{0};base64,{1}", "jpg", Convert.ToBase64String(arr));
string str = d.Substring(d.IndexOf(",") + 1);
return str;
}
/// <summary>
/// byte转换base64
/// </summary>
/// <param name="图片名字"></param>
/// <returns></returns>
public static string getbyteBase64(byte[] fileName)
{
byte[] arr = fileName;
var d = string.Format("data:image/{0};base64,{1}", "png", Convert.ToBase64String(arr));
string str = d.Substring(d.IndexOf(",") + 1);
return str;
}
/// <summary>
/// 从ftp获取图片
/// </summary>
/// <param name="url">路径</param>
/// <returns></returns>
public static byte[] FileImage(string url, string ftp = "")
{
//Logs.WriteLog("222获取图片开始"+DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"));
if (ftp != "")
{
url = "ftp://auth.blv-oa.com:50/uts_Manager/oyl_FTP/Image/" + url;
}
else
{
url = "ftp://auth.blv-oa.com:50/uts_Manager/oyl_FTP/Image/" + url;
}
FtpWebRequest ftpWeb;
try
{
ServicePointManager.ServerCertificateValidationCallback =
new RemoteCertificateValidationCallback(ValidateServerCertificate);
try
{
ftpWeb = (FtpWebRequest)FtpWebRequest.Create(url);//创建ftp连接
ftpWeb.Credentials = new NetworkCredential("uts_manager", "uts_Inhaos@all");//账号,密码
ftpWeb.KeepAlive = false;
ftpWeb.EnableSsl = false;
ftpWeb.Method = WebRequestMethods.Ftp.DownloadFile;
ftpWeb.UseBinary = true;
ftpWeb.UsePassive = true;
WebResponse ftpResponse = (FtpWebResponse)ftpWeb.GetResponse();
Stream ftpStream = ftpResponse.GetResponseStream();//获取图片流
MemoryStream outstream = new MemoryStream();//转成MS流
int bufferLen = 4096;//缓冲区
byte[] buffer = new byte[bufferLen];
int count = 0;
while ((count = ftpStream.Read(buffer, 0, bufferLen)) > 0)
{
outstream.Write(buffer, 0, count);
}
var img = outstream.ToArray();
ftpResponse.Close();
ftpStream.Close();
outstream.Close();
return img;
}
catch (Exception e)
{
LogHelper.WriteLine(e.Message);
return null;
}
}
catch (Exception ex)
{
LogHelper.WriteLine(ex.Message);
return null;
}
}
/// <summary>
/// 从YH获取文件
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public static string YHFileImage(string url)
{
//Logs.WriteLog("222获取图片开始"+DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"));
url = "ftp://auth.blv-oa.com:50/uts_Manager/oyl_FTP/YH/" + url;
FtpWebRequest ftpWeb;
try
{
ServicePointManager.ServerCertificateValidationCallback =
new RemoteCertificateValidationCallback(ValidateServerCertificate);
try
{
ftpWeb = (FtpWebRequest)FtpWebRequest.Create(url);//创建ftp连接
ftpWeb.Credentials = new NetworkCredential("uts_manager", "uts_Inhaos@all");//账号,密码
ftpWeb.KeepAlive = false;
ftpWeb.EnableSsl = false;
ftpWeb.Method = WebRequestMethods.Ftp.DownloadFile;
ftpWeb.UseBinary = true;
ftpWeb.UsePassive = true;
//AUTS.Services.Manager.Logs.WriteLog("获取图片数据开始" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"));
WebResponse ftpResponse = (FtpWebResponse)ftpWeb.GetResponse();
//AUTS.Services.Manager.Logs.WriteLog("获取图片数据结束" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff"));
Stream ftpStream = ftpResponse.GetResponseStream();//获取图片流
MemoryStream outstream = new MemoryStream();//转成MS流
int bufferLen = 4096;//缓冲区
byte[] buffer = new byte[bufferLen];
int count = 0;
while ((count = ftpStream.Read(buffer, 0, bufferLen)) > 0)
{
outstream.Write(buffer, 0, count);
}
//var img = outstream.ToArray();
//Logs.WriteLog(img.ToString());
var img = outstream.ToArray();
ftpResponse.Close();
ftpStream.Close();
outstream.Close();
return getbyteBase64(img);
//return File(img, "image/jpeg");
//return new Task<byte[]>(() => outstream.ToArray());
}
catch (Exception e)
{
return null;
}
}
catch (Exception ex)
{
return null;
}
}
/// <summary>
/// 无证书Ftp操作
/// </summary>
/// <param name="sender"></param>
/// <param name="certificate"></param>
/// <param name="chain"></param>
/// <param name="sslPolicyErrors"></param>
/// <returns></returns>
public static bool ValidateServerCertificate
(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}
/// <summary>
/// URL图片转换成图片格式
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
#region Image To base64
public static Image UrlToImage(string url)
{
WebClient mywebclient = new WebClient();
try
{
byte[] Bytes = mywebclient.DownloadData(url);
using (MemoryStream ms = new MemoryStream(Bytes))
{
Image outputImg = Image.FromStream(ms);
return outputImg;
}
}
catch (Exception ex)
{
LogHelper.WriteLine(ex.Message);
//Console.WriteLine("地址有误");
throw;
}
}
/// <summary>
/// 读取图片文件
/// </summary>
/// <param name="path">图片文件路径</param>
/// <returns>图片文件</returns>
private Bitmap ReadImageFile(String path)
{
Bitmap bitmap = null;
try
{
FileStream fileStream = File.OpenRead(path);
Int32 filelength = 0;
filelength = (int)fileStream.Length;
Byte[] image = new Byte[filelength];
fileStream.Read(image, 0, filelength);
System.Drawing.Image result = System.Drawing.Image.FromStream(fileStream);
fileStream.Close();
bitmap = new Bitmap(result);
}
catch (Exception ex)
{
// 异常输出
LogHelper.WriteLine(ex.Message);
}
return bitmap;
}
/// <summary>
/// Image 转成 base64
/// </summary>
/// <param name="fileFullName"></param>
public static string ImageToBase64(Image img)
{
try
{
Bitmap bmp = new Bitmap(img);
MemoryStream ms = new MemoryStream();
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
//Console.WriteLine(ms.Length);
byte[] arr = new byte[ms.Length];
ms.Position = 0;
ms.Read(arr, 0, (int)ms.Length);
ms.Close();
return Convert.ToBase64String(arr);
}
catch (Exception ex)
{
LogHelper.WriteLine(ex.Message);
return null;
}
}
public static string ImageToBase64(string url)
{
return ImageToBase64(UrlToImage(url));
}
#endregion
/// <summary>
/// 处理人脸机返回信息错误
/// </summary>
/// <param name="info"></param>
public static void Facereturuhandlingmethod(string info, string msgid)
{
try
{
Faceinfo finfo = JsonConvert.DeserializeObject<Faceinfo>(info);
if (finfo != null)
{
faceerrormsg fmsg = new faceerrormsg();
devicemanage devinfo = SqlSugarBase.FaceDb.Queryable<devicemanage>().First(it => it.SerialNo == finfo.sn);
if (devinfo != null)
{
if (devinfo.Factory == "移海")
{
//magsinfo ms = JsonConvert.DeserializeObject<magsinfo>(finfo.msg);
if (finfo.msg.Para.ErrCode != 0)
{
fmsg.brandinfo = "yh";
fmsg.errorcode = finfo.msg.Para.ErrCode;
fmsg.errormsg = finfo.msg.Para.ErrMsg;
fmsg.creationtime = DateTime.Now;
fmsg.sn = finfo.sn;
fmsg.step = 514;
fmsg.pmsid = IsLikeGuidByArr(msgid) ? -1 : int.Parse(msgid);
fmsg.remary = "人脸机回复失败信息";
fmsg.APKVersion = devinfo.APKVersion;
fmsg.hotelid = devinfo.HotelCode;
fmsg.Roomid = devinfo.RoomId.ToString();
fmsg.cmd = finfo.cmd;
int d = SqlSugarBase.FaceDb.Insertable(fmsg).ExecuteCommand();
}
}
}
}
}
catch (Exception e)
{
LogHelper.Write("控制台收到人脸机信息,处理命令时异常: " + e.Message + " 收到设备端上报的内容:" + info);
}
}
public static string GetBaiduIp(string ip)
{
string location = "";
try
{
string url = $"https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?query={ip}&co=&resource_id=6006&oe=utf8";
WebClient client = new WebClient();
var buffer = client.DownloadData(url);
string jsonText = Encoding.UTF8.GetString(buffer);
JObject jo = JObject.Parse(jsonText);
Root root = JsonConvert.DeserializeObject<Root>(jo.ToString());
foreach (var item in root.data)
{
location = item.location;
}
return location;
}
catch (Exception ex)
{
//Console.WriteLine(ex);
return location;
}
}
static bool IsLikeGuidByArr(string strSrc)
{
string testStr;
testStr = strSrc.Trim();
if (String.IsNullOrEmpty(strSrc)) { return false; }
for (int i = 0; i < testStr.Length; i++)
{
char a = testStr[i];
if (a == '-' || (a >= 'a' && a <= 'z') || (a >= 'A' && a <= 'Z'))
{
return true;
}
}
return false;
}
}
}