|
|
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Linq;
|
|
|
using System.Text;
|
|
|
using Mesnac.Compressor.Entity;
|
|
|
using System.Threading;
|
|
|
using Mesnac.Compressor.Unity;
|
|
|
|
|
|
namespace SocketProcess
|
|
|
{
|
|
|
public class SocketFactory
|
|
|
{
|
|
|
public EventHandler MesRecieved;
|
|
|
|
|
|
/// <summary>
|
|
|
/// 更换机种
|
|
|
/// </summary>
|
|
|
public EventHandler ChangeMachine;
|
|
|
|
|
|
/// <summary>
|
|
|
/// 各个机种的作业指导书下载
|
|
|
/// </summary>
|
|
|
public EventHandler ChangeMachinePicture;
|
|
|
|
|
|
|
|
|
#region 检验是否断开
|
|
|
readonly object ob = new object();
|
|
|
|
|
|
Thread readThread;
|
|
|
private void ThreadCheck()
|
|
|
{
|
|
|
if (readThread != null)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
readThread.Abort();
|
|
|
}
|
|
|
catch { }
|
|
|
readThread = null;
|
|
|
}
|
|
|
readThread = new Thread(loop);
|
|
|
readThread.Start();
|
|
|
|
|
|
}
|
|
|
|
|
|
private void loop()
|
|
|
{
|
|
|
Thread.Sleep(1000);
|
|
|
while (true)
|
|
|
{
|
|
|
CheckConnect();
|
|
|
Thread.Sleep(5000);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private void CheckConnect()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
foreach (var equip in SocketEquipList)
|
|
|
{
|
|
|
SocketClient client = equip.Socket;
|
|
|
DateTime readtime = client.lastRecieveTime;
|
|
|
DateTime now = DateTime.Now;
|
|
|
var span = now - readtime;
|
|
|
if (span.TotalSeconds > 5)
|
|
|
{
|
|
|
ICSharpCode.Core.LoggingService.Info("超时未读取数据:" + equip.IP+" 重新连接");
|
|
|
lock (ob)
|
|
|
{
|
|
|
client.ReConnect();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
catch(Exception e)
|
|
|
{
|
|
|
ICSharpCode.Core.LoggingService.Error("socket重连失败"+e.ToString());
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
#region 单例模式
|
|
|
private static SocketFactory _instance;
|
|
|
|
|
|
private readonly static object syabc = new object();
|
|
|
|
|
|
public static SocketFactory Instance
|
|
|
{
|
|
|
get
|
|
|
{
|
|
|
if (_instance == null)
|
|
|
{
|
|
|
lock (syabc)
|
|
|
{
|
|
|
_instance = new SocketFactory();
|
|
|
}
|
|
|
}
|
|
|
return _instance;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
public List<SocketEqiup> SocketEquipList = TrayFactory.Instance.SocketEquipList;
|
|
|
|
|
|
public SocketFactory()
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
public void Init()
|
|
|
{
|
|
|
//AllBindEvent();
|
|
|
Common.Instance.SocketReconnect += SocketReconnect;
|
|
|
AllConnect();
|
|
|
//ThreadCheck();
|
|
|
}
|
|
|
|
|
|
public void SocketReconnect(object sender,EventArgs e)
|
|
|
{
|
|
|
foreach (SocketEqiup se in SocketEquipList)
|
|
|
{
|
|
|
se.Socket.ReConnect();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 连接所有Socket
|
|
|
/// </summary>
|
|
|
private void AllConnect()
|
|
|
{
|
|
|
foreach (SocketEqiup se in SocketEquipList)
|
|
|
{
|
|
|
//Console.Write("Socket连接个数:" + SocketEquipList.Count.ToString());
|
|
|
se.Socket = new SocketClient(se.IP, se.Port);
|
|
|
//事件绑定
|
|
|
//Console.WriteLine(se.IP + "事件绑定");
|
|
|
se.Socket.OnMsgReceived += OnRecieveData;
|
|
|
//Connect(se);
|
|
|
Thread SocketThread = null;
|
|
|
SocketThread = new Thread(Connect);
|
|
|
SocketThread.Start(se);
|
|
|
//System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(Connect),se);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private void Connect(object o)
|
|
|
{
|
|
|
SocketEqiup equip = (SocketEqiup)o;
|
|
|
SocketClient client = equip.Socket;
|
|
|
|
|
|
try
|
|
|
{
|
|
|
if (!client.Connect())
|
|
|
{
|
|
|
Common.Instance.SocketConnect = false;
|
|
|
////初始化错误2017
|
|
|
//ICSharpCode.Core.MessageService.ShowCustomDialog("服务器连接失败", "IP:" + client.ho + "端口号:" + client.port);
|
|
|
ICSharpCode.Core.LoggingService.Error("Socket连接失败,IP:" + client.hostName + "端口号:" + client.port);
|
|
|
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
equip.IsConnect = true;
|
|
|
//Common.Instance.SocketConnect = true;
|
|
|
|
|
|
////这个地方不好,容易导致Socket连接错误
|
|
|
if (equip.EquipType == EquipType.RFIDSocket)
|
|
|
{
|
|
|
//开机下发手动模式
|
|
|
equip.Socket.Send("A5 5A 00 09 AA 01 A2 0D 0A");
|
|
|
//清除过滤信息
|
|
|
//FlatClear(equip);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
catch(Exception e)
|
|
|
{
|
|
|
ICSharpCode.Core.LoggingService.Error("Socket错误:" + e.ToString());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//事件绑定
|
|
|
private void AllBindEvent()
|
|
|
{
|
|
|
foreach (SocketEqiup se in SocketEquipList)
|
|
|
{
|
|
|
//事件绑定
|
|
|
//Console.WriteLine(se.IP+"事件绑定");
|
|
|
se.Socket.OnMsgReceived += OnRecieveData;
|
|
|
se.Socket.OnSended += OnSendComplete;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private void OnRecieveData(SocketMessage SM)
|
|
|
{
|
|
|
string abc = RfidWorkType.ChangeMachine.ToString();
|
|
|
DataHandler dhb = new DataHandler();
|
|
|
//ICSharpCode.Core.LoggingService.Info("收到数据,开始解析:" + SM.Message);
|
|
|
FrameFormat frame = dhb.DataAnylysis(SM.Message);
|
|
|
if (frame.Type == null)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
if (frame.CompleteFlag)
|
|
|
{
|
|
|
bool newEPC = false;
|
|
|
string autotype = Convert.ToString((int)RfidWorkType.setAutoUp, 16);
|
|
|
string ReadOneType = Convert.ToString((int)RfidWorkType.ReadOneReturn, 16);
|
|
|
|
|
|
#region 自动上报模式
|
|
|
//Console.WriteLine("读到数据" + frame.data.Epc + "IP:" + frame.data.IP + "天线号:" + frame.data.ANT);
|
|
|
//自动上报模式是BB
|
|
|
if (frame.Type.ToLower() == autotype)
|
|
|
{
|
|
|
//如果读到标签和我们的规则不一样,直接返回
|
|
|
if (frame.data.Epc.Substring(0, 20) != "00000000000000000000")
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
foreach (Station tl in Common.Instance.StationList)
|
|
|
{
|
|
|
string ip = Convert.ToInt32(frame.data.IP, 16).ToString();
|
|
|
|
|
|
//查找Sation的IP和天线号
|
|
|
if (tl.Ant == frame.data.ANT && tl.IP == ip)
|
|
|
{
|
|
|
//处理返回信息
|
|
|
SocketReturn(frame, SM.Client);
|
|
|
|
|
|
//过滤重复数据
|
|
|
//暂时去掉yinzf 2017-04-11
|
|
|
if (frame.data.Epc != tl.LastScanCode || !tl.IsRFIDAvailable())
|
|
|
{
|
|
|
//yinzf 17-05-03目前所有的工位都是删除已有标签
|
|
|
//如果已存在标签,删除
|
|
|
if (tl.IsRFIDAvailable() && tl.DeletePreRFID)
|
|
|
{
|
|
|
ICSharpCode.Core.LoggingService.Info("同一工位读到两个RFID,删除上一个标签");
|
|
|
tl.DeleteTyre();
|
|
|
}
|
|
|
else if (tl.IsRFIDAvailable())
|
|
|
{
|
|
|
//C4工位,不能删除上次的标签。
|
|
|
return;
|
|
|
}
|
|
|
///测试用 16-12-15 主要是为了直接获取数据
|
|
|
///目前不管有没有托盘到位请求,只要收到作业完成信号就会保存数据,放行
|
|
|
frame.data.HaveWorked = true;
|
|
|
//测试完成
|
|
|
//Console.WriteLine("比对成功,插入队列" + frame.data.Epc);
|
|
|
newEPC = tl.InsertQueue(frame.data);
|
|
|
if (newEPC)
|
|
|
{
|
|
|
tl.LastScanCode = frame.data.Epc;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
|
|
|
#region 单次读标签
|
|
|
if (frame.Type.ToLower() == ReadOneType)
|
|
|
{
|
|
|
//if ((!string.IsNullOrEmpty(frame.data.Epc))&&frame.data.Epc.Substring(0, 20) != "00000000000000000000")
|
|
|
|
|
|
foreach (Station tl in Common.Instance.StationList)
|
|
|
{
|
|
|
string ip = Convert.ToInt32(frame.data.IP, 16).ToString();
|
|
|
//查找Sation的IP和天线号
|
|
|
if (tl.Ant == frame.data.ANT && tl.IP == ip)
|
|
|
{
|
|
|
if (string.IsNullOrEmpty(frame.data.Epc))
|
|
|
{
|
|
|
ICSharpCode.Core.LoggingService.Info("读写器返回"+tl.StationName + "空");
|
|
|
if (tl.ReadTimes < 4)
|
|
|
{
|
|
|
ReadOneTag(tl);
|
|
|
//tl.ReadTimes++;
|
|
|
}
|
|
|
return;
|
|
|
}
|
|
|
if (frame.data.Epc.Substring(0, 20) != "00000000000000000000")
|
|
|
{
|
|
|
ICSharpCode.Core.LoggingService.Info(tl.StationName + "读到标签编码格式不正确:" + frame.data.Epc);
|
|
|
return;
|
|
|
}
|
|
|
ICSharpCode.Core.LoggingService.Info(tl.StationName + "读到标签:" + frame.data.Epc);
|
|
|
//如果已存在标签,且该工位标签可以覆盖,删除上一个
|
|
|
if (tl.IsRFIDAvailable() && tl.DeletePreRFID)
|
|
|
{
|
|
|
ICSharpCode.Core.LoggingService.Info("读到新标签,删除上一个标签");
|
|
|
tl.DeleteTyre();
|
|
|
}
|
|
|
else if (tl.IsRFIDAvailable())
|
|
|
{
|
|
|
//C4工位,不能删除上次的标签。
|
|
|
return;
|
|
|
}
|
|
|
///测试用 16-12-15 主要是为了直接获取数据
|
|
|
///目前不管有没有托盘到位请求,只要收到作业完成信号就会保存数据,放行
|
|
|
frame.data.HaveWorked = true;
|
|
|
//测试完成
|
|
|
ICSharpCode.Core.LoggingService.Info("插入队列" + tl.StationName + frame.data.Epc);
|
|
|
tl.InsertQueue(frame.data);
|
|
|
}
|
|
|
}
|
|
|
#endregion
|
|
|
//界面处理函数,有新的标签的时候才能进行事件调用
|
|
|
if (MesRecieved != null)
|
|
|
{
|
|
|
MesRecieved(null, null);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
//更换机种时间
|
|
|
else if (frame.Type.ToLower() == Convert.ToString((int)RfidWorkType.ChangeMachine, 16))
|
|
|
{
|
|
|
if (ChangeMachine != null)
|
|
|
{
|
|
|
ChangeMachine(null, null);
|
|
|
}
|
|
|
}
|
|
|
////更换图片
|
|
|
//else if (frame.Type.ToLower() == Convert.ToString((int)RfidWorkType.DownLoadPicture, 16))
|
|
|
//{
|
|
|
// if (ChangeMachinePicture != null)
|
|
|
// {
|
|
|
// ChangeMachinePicture(null, null);
|
|
|
// }
|
|
|
//}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private void OnSendComplete(bool result)
|
|
|
{
|
|
|
if (!result)
|
|
|
{
|
|
|
////
|
|
|
//Common.Instance.SocketConnect = false;
|
|
|
//FrmConnnectFlag frm = new FrmConnnectFlag();
|
|
|
//frm.ShowDialog();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//private void MegSave(FrameFormat frame)
|
|
|
//{
|
|
|
// if (frame.CompleteFlag)
|
|
|
// {
|
|
|
|
|
|
// if (frame.Type == "BB")
|
|
|
// {
|
|
|
// Console.WriteLine("解析成功,正在添加" + frame.data.Epc);
|
|
|
// foreach (Station tl in TrayFactory.Instance.StationList)
|
|
|
// {
|
|
|
// if (tl.Ant == frame.data.ANT && tl.IP == frame.data.IP)
|
|
|
// {
|
|
|
// Console.WriteLine("比对成功,插入队列" + frame.data.Epc);
|
|
|
// tl.InsertQueue(frame.data);
|
|
|
// }
|
|
|
// }
|
|
|
// }
|
|
|
// //处理返回信息
|
|
|
// SocketReturn(frame);
|
|
|
// //界面处理函数
|
|
|
// if (MesRecieved != null)
|
|
|
// {
|
|
|
// MesRecieved(null, null);
|
|
|
// }
|
|
|
// }
|
|
|
|
|
|
//}
|
|
|
private void SocketReturn(FrameFormat frame,SocketClient client)
|
|
|
{
|
|
|
int type = Convert.ToInt32(frame.Type, 16);
|
|
|
switch (type)
|
|
|
{
|
|
|
case (int)RfidWorkType.setAutoUp:
|
|
|
//返回此EPC不用再上传
|
|
|
//DataHandler dh = new DataHandler();
|
|
|
//string typed = "AC";
|
|
|
//string flatEpc = dh.FrameConbine(frame.data, typed);
|
|
|
//Console.WriteLine("返回EPC过滤信息:" + flatEpc + "EPC号:" + frame.data.Epc);
|
|
|
//client.Send(flatEpc);
|
|
|
FlatEPC(frame.data, client);
|
|
|
break;
|
|
|
case (int)RfidWorkType.setFlatEpcReturn:
|
|
|
//这个不用管吧
|
|
|
|
|
|
break;
|
|
|
default:
|
|
|
//只要不是这两种模式,就设置为自动上报模式
|
|
|
//string autoMode = "A5 5a 00 09 AA 00 A3 0D 0A";
|
|
|
//client.Send(autoMode);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 过滤EPC数据
|
|
|
/// </summary>
|
|
|
/// <param name="frame"></param>
|
|
|
/// <param name="client"></param>
|
|
|
public void FlatEPC(DataFormat frame, SocketClient client)
|
|
|
{
|
|
|
//DataHandler dh = new DataHandler();
|
|
|
//string typed = "AC";
|
|
|
//string flatEpc = dh.FrameConbine(frame, typed);
|
|
|
//// Mesnac.Log.LogService.Instance.Debug(flatEpc);
|
|
|
//client.Send(flatEpc);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 向服务器发送数据
|
|
|
/// </summary>
|
|
|
/// <param name="Type">帧类型</param>
|
|
|
/// <param name="Message">数据</param>
|
|
|
public void SendToServer(string Type,string Message)
|
|
|
{
|
|
|
DataFormat df = new DataFormat();
|
|
|
df.Epc = Message;
|
|
|
df.ANT = "";
|
|
|
DataHandler dbhandler = new DataHandler();
|
|
|
string frame = dbhandler.FrameConbine(df, Type);
|
|
|
SocketClient ServerClient=FindServer();
|
|
|
if (ServerClient == null)
|
|
|
{
|
|
|
Mesnac.Log.LogService.Instance.Debug("没找到Server服务器");
|
|
|
// Mesnac.Log.LogService.Instance.Debug("没找到Server服务器");
|
|
|
return;
|
|
|
}
|
|
|
ServerClient.Send(frame);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 找到服务器的Socket
|
|
|
/// </summary>
|
|
|
/// <returns></returns>
|
|
|
private SocketClient FindServer()
|
|
|
{
|
|
|
SocketClient ServerClient=null;
|
|
|
foreach (SocketEqiup sc in Instance.SocketEquipList)
|
|
|
{
|
|
|
if (sc.EquipType == EquipType.ServerSocket)
|
|
|
{
|
|
|
ServerClient = sc.Socket;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
return ServerClient;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 清空过滤信息
|
|
|
/// </summary>
|
|
|
public void FlatClear()
|
|
|
{
|
|
|
foreach (SocketEqiup se in SocketEquipList)
|
|
|
{
|
|
|
lock (se)
|
|
|
{
|
|
|
foreach (Station stat in Common.Instance.StationList)
|
|
|
{
|
|
|
if (stat.StationType == "VartualStation")
|
|
|
continue;
|
|
|
string IP = "192.168.0." + stat.IP;
|
|
|
if (se.IP == IP && se.IsConnect)
|
|
|
{
|
|
|
Console.WriteLine("SocketIP:" + se.IP.ToString() + "站IP:" + stat.IP + " 天线:" + stat.Ant);
|
|
|
DataFormat df = new DataFormat();
|
|
|
df.ANT = stat.Ant;
|
|
|
df.Epc = "000000000000000000000000";
|
|
|
FlatEPC(df, se.Socket);
|
|
|
}
|
|
|
Thread.Sleep(100);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public void ReadOneTag(Station station)
|
|
|
{
|
|
|
foreach (SocketEqiup se in SocketEquipList)
|
|
|
{
|
|
|
if (station.StationType == "VartualStation")
|
|
|
continue;
|
|
|
string IP = "192.168.0." + station.IP;
|
|
|
if (se.IP == IP && se.IsConnect)
|
|
|
{
|
|
|
lock (se)
|
|
|
{
|
|
|
//Console.WriteLine("SocketIP:" + se.IP.ToString() + "站IP:" + station.IP + " 天线:" + station.Ant);
|
|
|
DataHandler dh = new DataHandler();
|
|
|
string sendMessage = dh.ReadOneStringCombine(station.Ant);
|
|
|
//ICSharpCode.Core.LoggingService.Warn(station.StationName+"发送读取指令");
|
|
|
ICSharpCode.Core.LoggingService.Info("工位:" + station.StationName + " 第" + station.ReadTimes.ToString() + "次读取");
|
|
|
se.Socket.Send(sendMessage);
|
|
|
station.ReadTimes++;
|
|
|
}
|
|
|
}
|
|
|
Thread.Sleep(100);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|