#region [自定义类-VS][20250701112200484][AutoThread]
|
using Newtonsoft.Json;
|
using System;
|
using System.Collections.Generic;
|
using System.Collections.Concurrent;
|
using System.ComponentModel;
|
using System.Linq;
|
using System.Reflection;
|
using System.Text;
|
using System.Threading.Tasks;
|
using GZ.Modular.Redis;
|
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
|
using System.Windows.Interop;
|
using static System.Windows.Forms.VisualStyles.VisualStyleElement.TextBox;
|
using System.Security.Cryptography;
|
using System.Windows.Markup;
|
using static System.Runtime.CompilerServices.RuntimeHelpers;
|
using ServiceStack.Configuration;
|
using ServiceStack;
|
using static Dapper.SqlMapper;
|
using System.IO;
|
using System.Net.WebSockets;
|
using System.Net;
|
using System.Threading;
|
using System.Net.Sockets;
|
using NLog.Config;
|
using NLog.Targets;
|
using NLog;
|
using ServiceStack.Messaging.Rcon;
|
using System.Runtime.ExceptionServices;
|
using System.Runtime.InteropServices;
|
using System.Security.RightsManagement;
|
using static GZ.Projects.HnSx.Clloc.sendTask;
|
using static GZ.Projects.HnSx.Clloc.modifyTaskPriority;
|
using static GZ.Projects.HnSx.Clloc.stockInException;
|
using static GZ.Projects.HnSx.Clloc.taskFeedback;
|
using static GZ.Projects.HnSx.Clloc.stockInInteraction;
|
using static GZ.Projects.HnSx.Clloc.cancelTask;
|
using static GZ.Projects.HnSx.Clloc.palletStackerInteraction;
|
using static GZ.Projects.HnSx.Clloc.putConveyorTask;
|
using static GZ.Projects.HnSx.Clloc.reportWeightinfo;
|
using System.Threading.Channels;
|
using static GZ.Projects.HnSx.Clloc;
|
|
namespace GZ.Projects.HnSx
|
{
|
public partial class AutoThread
|
{
|
|
private static AutoThread _instance;
|
|
// 私有构造函数防止外部实例化
|
private AutoThread() { }
|
|
public static AutoThread Instance
|
{
|
get
|
{
|
if (_instance == null)
|
{
|
_instance = new AutoThread();
|
}
|
return _instance;
|
}
|
}
|
|
// 线程安全的委托缓存
|
private static readonly ConcurrentDictionary<string, Delegate> _methodCache = new ConcurrentDictionary<string, Delegate>();
|
|
// 方法执行器
|
public static object InvokeMethod(object instance, string methodName, params object[] args)
|
{
|
var cacheKey = $"{instance.GetType().FullName}_{methodName}";
|
|
if (!_methodCache.TryGetValue(cacheKey, out var methodDelegate))
|
{
|
// 获取方法信息
|
var methodInfo = instance.GetType().GetMethod(
|
methodName,
|
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
|
if (methodInfo == null)
|
throw new MissingMethodException($"Method {methodName} not found");
|
|
// 创建委托并缓存
|
methodDelegate = Delegate.CreateDelegate(
|
GetDelegateType(methodInfo),
|
instance,
|
methodInfo);
|
|
_methodCache.TryAdd(cacheKey, methodDelegate);
|
}
|
|
// 执行委托
|
return methodDelegate.DynamicInvoke(args);
|
}
|
|
// 根据方法签名生成对应的委托类型
|
private static Type GetDelegateType(MethodInfo methodInfo)
|
{
|
var parameterTypes = methodInfo.GetParameters()
|
.Select(p => p.ParameterType)
|
.ToList();
|
|
if (methodInfo.ReturnType == typeof(void))
|
{
|
return System.Linq.Expressions.Expression.GetActionType(parameterTypes.ToArray());
|
}
|
else
|
{
|
parameterTypes.Add(methodInfo.ReturnType);
|
return System.Linq.Expressions.Expression.GetFuncType(parameterTypes.ToArray());
|
}
|
}
|
|
/// <summary>
|
/// 配置初始化。
|
/// </summary>
|
/// <param name="tag"></param>
|
/// <param name="action"></param>
|
public void ThreadSettingInit(Tag tag)
|
{
|
}
|
|
public async void ThreadwebSoc()
|
{
|
//read Alldata from database
|
//将数据缓存到内存。
|
try
|
{
|
Thread.Sleep(1000);
|
while (true)
|
{
|
if (/*list.Count > 0 && */WebSocketClientWithReconnect.GetWebSocketState() == WebSocketState.Open)
|
for (int i = 0; i < 70000; i++)
|
{
|
Thread.Sleep(1000);
|
Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")}>>>发送 第 {i} 条");
|
//LogHelper.Info($"Hello Server {i}");
|
var req = new ReportWeightInfoRequest
|
{
|
data = new ReportWeightInfoData
|
{
|
header = new ReportWeightInfoHeader
|
{
|
deliveryNo = "F0000" + i,
|
grossWeight = i,
|
cube = i,
|
addTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"),
|
addWho = "WCS"
|
}
|
}
|
};
|
var b = WebSocketClientWithReconnect.Instance?.SendAsync(JsonConvert.SerializeObject(req)).Result;
|
Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")}>>发送完成!!" + b);
|
if (b == true)
|
{
|
// 等待特定响应
|
|
var rr = reportWeightinfo.GetChinnnl().Result;
|
|
//LogHelper.Info($" {DateTime.Now.ToString("HH:mm:ss.fff")}>> 接收" + JsonConvert.SerializeObject(rr));
|
//}
|
Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")}>>" + JsonConvert.SerializeObject(rr));
|
}
|
else Console.WriteLine("发送失败。");
|
}
|
Thread.Sleep(1000);
|
}
|
}
|
catch (Exception ex)
|
{
|
LogHelper.Error(ex.Message, ex);
|
}
|
}
|
public async Task TaskEverythingRun()
|
{
|
var host = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName());
|
foreach (var ip in host.AddressList)
|
{
|
if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
|
{
|
Console.WriteLine($"ip= {ip.ToString()}");
|
new HttpServer(ip.ToString()).HttpServerRun();
|
//new TcpServer(ip.ToString());
|
//var server = new EnhancedWebSocketServer($"http://{ip.ToString()}:8809/").StartAsync(); http://10.20.66.121:18080
|
new WebSocketClientWithReconnect($"ws://10.20.66.121:20001/socket").StartAsync();
|
//new WebSocketClientWithReconnect($"ws://{ip.ToString()}:8809/socket").StartAsync();
|
WebSocketClientWithReconnect.Instance.OnMessageReceived += (msg) =>
|
{
|
//reportWeightinfo.channel.Writer.TryWrite(JsonConvert.DeserializeObject<ReportWeightInfoResponse>(msg));
|
reportWeightinfo.channel.Writer.TryWrite(new ReportWeightInfoResponse
|
{
|
Response = new ReportWeightInfoResponseData
|
{
|
Return = new ReportWeightInfoReturnInfo
|
{
|
returnCode = "0000",
|
sortingChute = msg
|
}
|
}
|
});
|
};
|
break;
|
}
|
}
|
}
|
|
|
|
}
|
public class HttpServer
|
{
|
public static readonly HttpHelper apiHelper = new HttpHelper();
|
System.Net.HttpListener HttpSvcHost = null;
|
|
public static string _listenerPrefix = "";
|
public HttpServer(string ip)
|
{
|
_listenerPrefix = $"http://{ip}:8808/";
|
}
|
public void HttpServerRun()
|
{
|
HttpSvcHost = new System.Net.HttpListener();
|
HttpSvcHost.AuthenticationSchemes = System.Net.AuthenticationSchemes.Anonymous;
|
HttpSvcHost.Prefixes.Add(_listenerPrefix);
|
HttpSvcHost.Start();
|
HttpSvcHost.BeginGetContext(HttpSvcListenerCallback, null);
|
}
|
|
private async void HttpSvcListenerCallback(IAsyncResult ar)
|
{
|
System.Net.HttpListenerContext context = null;
|
var data = DateTime.Now;
|
string apth = "";
|
try
|
{
|
HttpSvcHost.BeginGetContext(HttpSvcListenerCallback, null);
|
context = HttpSvcHost.EndGetContext(ar);
|
System.Net.HttpListenerRequest request = context.Request;
|
System.Net.HttpListenerResponse response = context.Response;
|
|
using (var reader = new System.IO.StreamReader(request.InputStream, System.Text.Encoding.UTF8))
|
{
|
string requestJson = reader.ReadToEnd();
|
System.Net.HttpStatusCode statusCode = 0;
|
apth = request.Url.AbsolutePath;
|
string respstr = HttpSvcListenerCallback_he(request.HttpMethod, request.Url.AbsolutePath, requestJson, out statusCode);
|
string logContent = "";
|
logContent += $"\r\n[{request.HttpMethod}]{request.Url.AbsolutePath}";
|
logContent += $"\r\n[request]{requestJson}";
|
logContent += $"\r\n[response]{respstr}";
|
_ = Task.Run(() =>
|
{
|
LogHelper.Info(logContent);
|
Conn.log默认日志?.Info(logContent);
|
});
|
byte[] bytstr = Encoding.UTF8.GetBytes(respstr);
|
response.StatusCode = (int)statusCode;
|
response.SendChunked = false;
|
response.ContentLength64 = bytstr.Length;
|
if (request.Url.AbsolutePath.ToLower().Contains(".js"))
|
response.ContentType = "application/javascript";
|
else if (request.Url.AbsolutePath.ToLower().Contains(".svg"))
|
response.ContentType = "image/svg+xml";
|
// 异步写入响应
|
await response.OutputStream.WriteAsync(bytstr, 0, bytstr.Length);
|
}
|
}
|
catch (Exception ex)
|
{
|
_ = Task.Run(() =>
|
{
|
Conn.log默认日志.Error(ex.ToString());
|
});
|
}
|
finally
|
{
|
context?.Response.Close();
|
Console.WriteLine(apth + "<<>>" + DateTime.Now.Subtract(data).TotalMilliseconds);
|
}
|
}
|
public static List<SendTaskHeader> lstr = new List<SendTaskHeader>();
|
public static List<PutConveyorTaskHeader> putConveyorTasks = new List<PutConveyorTaskHeader>();
|
|
private System.String HttpSvcListenerCallback_he(System.String method, System.String path, System.String requestJson, out System.Net.HttpStatusCode statusCode)
|
{
|
try
|
{
|
switch (method)
|
{
|
case "POST":
|
{
|
switch (path)
|
{
|
case "/api/Wcs/GetTask":
|
{
|
statusCode = System.Net.HttpStatusCode.OK;
|
return JsonConvert.SerializeObject(new
|
{
|
出入移库任务 = lstr,
|
箱体分发任务 = putConveyorTasks
|
});
|
break;
|
}
|
case "/api/Wcs/RemoveTask":
|
{
|
statusCode = System.Net.HttpStatusCode.OK;
|
lstr.RemoveAll(x => x.palletId == requestJson);
|
putConveyorTasks.RemoveAll(x => x.palletId == requestJson);
|
break;
|
}
|
///任务下发--WMS-->WC
|
case "/api/Wcs/sendTask":
|
{
|
statusCode = System.Net.HttpStatusCode.OK;
|
var req = JsonConvert.DeserializeObject<SendTaskRequest>(requestJson);
|
if (req == null || req.data == null || lstr.Find(x => x.groupTaskSequence == req.data.header.groupTaskSequence && x.groupTaskId == req.data.header.groupTaskId) != null)
|
{
|
if (req == null || req.data == null)
|
|
return JsonConvert.SerializeObject(new SendTaskResponse
|
{
|
Response = new ResponseData
|
{
|
Return = new ReturnInfo
|
{
|
returnCode = "0001",
|
returnDesc = req?.data == null ? "无任务下发!" : "任务重复下发!",
|
returnFlag = "0"
|
}
|
}
|
});
|
else
|
return JsonConvert.SerializeObject(new SendTaskResponse
|
{
|
Response = new ResponseData
|
{
|
Return = new ReturnInfo
|
{
|
returnCode = "0000",
|
returnDesc = "任务重复下发!",
|
returnFlag = "1"
|
}
|
}
|
});
|
}
|
lstr.Add(req.data.header);
|
return JsonConvert.SerializeObject(new SendTaskResponse
|
{
|
Response = new ResponseData
|
{
|
Return = new ReturnInfo
|
{
|
returnCode = "0000",
|
returnDesc = "ok",
|
returnFlag = "1"
|
}
|
}
|
});
|
}
|
///入库异常上报。 WCS-->WMS
|
case "/api/Wcs/stockInException":
|
{
|
statusCode = System.Net.HttpStatusCode.OK;
|
var f = string.IsNullOrEmpty(requestJson) ? lstr.FirstOrDefault() : lstr.Find(x => x.palletId == requestJson);
|
var str = apiHelper.Post("http://10.20.66.121:18080/datahubjson/wcs/?method=STOCKINEXCEP", JsonConvert.SerializeObject(new StockInExceptionRequest
|
{
|
data = new StockInExceptionData
|
{
|
header = new StockInExceptionHeader
|
{
|
organizationId = f.organizationId,
|
warehouseId = f.warehouseId,
|
groupTaskId = f.groupTaskId,
|
groupTaskSequence = f.groupTaskSequence,
|
palletId = f.palletId,
|
addTime = f.addTime.ToString("yyyy-MM-dd HH:mm:ss"),
|
addWho = f.addWho,
|
reason = "库位有货不可用",
|
reasonCode = "01"
|
}
|
}
|
}));
|
|
var strres = JsonConvert.DeserializeObject<StockInExceptionResponse>(str);
|
if (strres.Response.Return.returnCode == "0000")
|
{
|
f.toPosition = strres.Response.Return.toPosition;
|
f.toLocation = strres.Response.Return.toLocation;
|
}
|
return str;
|
}
|
///任务状态反馈 WCS-->WM
|
case "/api/Wcs/taskFeedback":
|
{
|
statusCode = System.Net.HttpStatusCode.OK;
|
//foreach (var statu in new List<string> { "", "" })
|
{
|
var f = string.IsNullOrEmpty(requestJson) ? lstr.FirstOrDefault() : lstr.Find(x => x.palletId == requestJson);
|
var str = apiHelper.Post("http://10.20.66.121:18080/datahubjson/wcs/?method=TASKFEEDBACK", JsonConvert.SerializeObject(new TaskFeedbackRequest
|
{
|
data = new TaskFeedbackData
|
{
|
header = new TaskFeedbackHeader
|
{
|
organizationId = f.organizationId,
|
warehouseId = f.warehouseId,
|
groupTaskId = f.groupTaskId,
|
groupTaskSequence = f.groupTaskSequence,
|
palletId = f.palletId,
|
fmLocation = f.fmLocation,
|
fmPosition = f.fmPosition,
|
toLocation = f.toLocation,
|
toPosition = f.toPosition,
|
taskStatus = "80",
|
taskType = f.taskType,
|
closeTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
|
closeWho = f.addWho
|
}
|
}
|
}));
|
}
|
return JsonConvert.SerializeObject("");
|
}
|
///入库交互 。WCS-->WMS
|
case "/api/Wcs/stockInInteraction":
|
{
|
statusCode = System.Net.HttpStatusCode.OK;
|
var req = JsonConvert.DeserializeObject<StockInInteractionRequest>(requestJson);
|
|
var str = apiHelper.Post("http://10.20.66.121:18080/datahubjson/wcs/?method=STOCKININTERACTION", requestJson);
|
//var str = @"{""Response"":{""return"":{""returnCode"":""0000"",""returnDesc"":""Success"",""returnFlag"":""1"",""groupTaskId"":""GT250708000001"",""groupTaskSequence"":""1"",""taskStatus"":""00"",""taskType"":""PA"",""priority"":""3"",""toLocation"":""5A070101"",""toPosition"":""01""}}}";
|
var res = JsonConvert.DeserializeObject<StockInInteractionResponse>(str);
|
if (res.Response.Return.returnCode == "0000")
|
{
|
var from = req.data.header;
|
var resss = res.Response.Return;
|
lstr.Add(new SendTaskHeader
|
{
|
groupTaskId = resss.groupTaskId,
|
groupTaskSequence = resss.groupTaskSequence,
|
fmLocation = from.fmLocation,
|
fmPosition = from.fmPosition,
|
palletId = from.palletId,
|
taskStatus = resss.taskStatus,
|
taskType = resss.taskType,
|
priority = resss.priority,
|
toLocation = resss.toLocation,
|
toPosition = resss.toPosition,
|
addTime = DateTime.Now,
|
addWho = from.addWho,
|
});
|
}
|
return str;// + JsonConvert.SerializeObject(lstr);
|
var str1 = apiHelper.Post("http://10.20.66.121:18080/datahubjson/wcs/?method=STOCKININTERACTION", JsonConvert.SerializeObject(new StockInInteractionRequest
|
{
|
data = new StockInInteractionData
|
{
|
header = new StockInInteractionHeader
|
{
|
palletId = "TP9901",
|
grossWeight = 99,
|
palletWidth = 99,
|
fmLocation = "",
|
fmPosition = "",
|
addTime = DateTime.Now,
|
addWho = ""
|
}
|
}
|
}));
|
return str1;
|
}
|
///入库交互 。WCS-->WMS
|
case "/api/Wcs/stockInInteraction2":
|
{
|
statusCode = System.Net.HttpStatusCode.OK;
|
var req = JsonConvert.DeserializeObject<StockInInteractionRequest>(requestJson);
|
|
var str = apiHelper.Post("http://10.20.66.121:18080/datahubjson/wcs/?method=STOCKININTERACTION", requestJson);
|
//var str = @"{""Response"":{""return"":{""returnCode"":""0000"",""returnDesc"":""Success"",""returnFlag"":""1"",""groupTaskId"":""GT250708000001"",""groupTaskSequence"":""1"",""taskStatus"":""00"",""taskType"":""PA"",""priority"":""3"",""toLocation"":""5A070101"",""toPosition"":""01""}}}";
|
var res = JsonConvert.DeserializeObject<StockInInteractionResponse>(str);
|
if (res.Response.Return.returnCode == "0000")
|
{
|
var from = req.data.header;
|
var resss = res.Response.Return;
|
lstr.Add(new SendTaskHeader
|
{
|
groupTaskId = resss.groupTaskId,
|
groupTaskSequence = resss.groupTaskSequence,
|
fmLocation = from.fmLocation,
|
fmPosition = from.fmPosition,
|
palletId = from.palletId,
|
taskStatus = resss.taskStatus,
|
taskType = resss.taskType,
|
priority = resss.priority,
|
toLocation = resss.toLocation,
|
toPosition = resss.toPosition,
|
addTime = DateTime.Now,
|
addWho = from.addWho,
|
});
|
}
|
return str;// + JsonConvert.SerializeObject(lstr);
|
var str1 = apiHelper.Post("http://10.20.66.121:18080/datahubjson/wcs/?method=STOCKININTERACTION", JsonConvert.SerializeObject(new StockInInteractionRequest
|
{
|
data = new StockInInteractionData
|
{
|
header = new StockInInteractionHeader
|
{
|
palletId = "TP9901",
|
grossWeight = 99,
|
palletWidth = 99,
|
fmLocation = "",
|
fmPosition = "",
|
addTime = DateTime.Now,
|
addWho = ""
|
}
|
}
|
}));
|
return str1;
|
}
|
|
///任务取消。 WMS-->WCS
|
case "/api/Wcs/cancelTask":
|
{
|
statusCode = System.Net.HttpStatusCode.OK;
|
var req = JsonConvert.DeserializeObject<CancelTaskRequest>(requestJson);
|
var task = lstr.Find(x => x.groupTaskId == req.data.header.groupTaskId && x.groupTaskSequence == req.data.header.groupTaskSequence);
|
if (task == null)
|
return JsonConvert.SerializeObject(new CancelTaskResponse
|
{
|
Response = new ResponseData
|
{
|
Return = new ReturnInfo
|
{
|
returnCode = "0001",
|
returnDesc = "任务不存在!!!",
|
returnFlag = "0"
|
}
|
}
|
});
|
lstr.Remove(task);
|
return JsonConvert.SerializeObject(new CancelTaskResponse
|
{
|
Response = new ResponseData
|
{
|
Return = new ReturnInfo
|
{
|
returnCode = "0000",
|
returnDesc = "",
|
returnFlag = "1"
|
}
|
}
|
});
|
}
|
/// 碟盘机申请任务。 WCS-->WMS
|
case "/api/Wcs/palletStackerInteraction":
|
{
|
statusCode = System.Net.HttpStatusCode.OK;
|
|
var str = apiHelper.Post("http://10.20.66.121:18080/datahubjson/wcs/?method=PALLETSTACKERINTERACTION", !string.IsNullOrEmpty(requestJson) ? requestJson : JsonConvert.SerializeObject(new PalletStackerInteractionRequest
|
{
|
data = new PalletStackerInteractionData
|
{
|
header = new PalletStackerInteractionHeader
|
{
|
palletId = "TP9901",
|
taskId = $"X{DateTime.Now.ToString("yyyyMMdd")}001",
|
taskType = "PI",
|
fmLocation = "2FC1076",
|
addTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
|
addWho = "wcs"
|
}
|
}
|
}));
|
return str;
|
//return JsonConvert.SerializeObject("");
|
}
|
///修改任务优先级 。 WMS - WCS
|
case "/api/Wcs/modifyTaskPriority":
|
{
|
statusCode = System.Net.HttpStatusCode.OK;
|
var req = JsonConvert.DeserializeObject<ModifyTaskPriorityRequest>(requestJson);
|
List<TaskErrorInfo> taskErrorInfos = new List<TaskErrorInfo>();
|
if (req != null)
|
{
|
foreach (var item in req.data.header)
|
{
|
var task = lstr.Find(x => x.groupTaskSequence == item.groupTaskSequence && x.groupTaskId == item.groupTaskId);
|
if (task != null)
|
{
|
task.priority = item.priority;
|
}
|
else
|
{
|
taskErrorInfos.Add(new TaskErrorInfo
|
{
|
groupTaskId = item.groupTaskId,
|
groupTaskSequence = item.groupTaskSequence,
|
errorCode = "0001",
|
errorDesc = "没这个任务"
|
});
|
}
|
}
|
|
}
|
|
if (req == null || req.data.header.Count == taskErrorInfos.Count)
|
return JsonConvert.SerializeObject(new ModifyTaskPriorityResponse
|
{
|
Response = new ModifyTaskPriorityResponseData
|
{
|
Return = new ModifyTaskPriorityReturnInfo
|
{
|
returnCode = "0001",
|
returnDesc = "没有任务可更改",
|
returnFlag = "0"
|
}
|
}
|
});
|
else
|
{
|
if (taskErrorInfos.Count == 0)
|
return JsonConvert.SerializeObject(new ModifyTaskPriorityResponse
|
{
|
Response = new ModifyTaskPriorityResponseData
|
{
|
Return = new ModifyTaskPriorityReturnInfo
|
{
|
returnCode = "0000",
|
returnFlag = "1",
|
returnDesc="ok"
|
}
|
}
|
});
|
else
|
{
|
return JsonConvert.SerializeObject(new ModifyTaskPriorityResponse
|
{
|
Response = new ModifyTaskPriorityResponseData
|
{
|
Return = new ModifyTaskPriorityReturnInfo
|
{
|
returnCode = "0001",
|
returnDesc = "部分任务可更改",
|
returnFlag = "2",
|
resultInfo = taskErrorInfos
|
}
|
}
|
});
|
}
|
}
|
|
}
|
/// 输送线任务推送。 WMS-->WCS -- 记录箱号数据,分拣下线后根据想好进入对应的区域。
|
case "/api/Wcs/putConveyorTask":
|
{
|
statusCode = System.Net.HttpStatusCode.OK;
|
var req = JsonConvert.DeserializeObject<PutConveyorTaskRequest>(requestJson);
|
List<TaskErrorInfo> taskErrorInfos = new List<TaskErrorInfo>();
|
if (req != null)
|
{
|
foreach (var item in req.data.header)
|
{
|
var task = putConveyorTasks.Find(x => x.groupTaskSequence == item.groupTaskSequence && x.groupTaskId == item.groupTaskId);
|
if (task == null)
|
{
|
putConveyorTasks.Add(item);
|
}
|
else
|
{
|
taskErrorInfos.Add(new TaskErrorInfo
|
{
|
groupTaskId = item.groupTaskId,
|
groupTaskSequence = item.groupTaskSequence,
|
errorCode = "0001",
|
errorDesc = "重复"
|
});
|
}
|
}
|
|
}
|
|
if (req == null || req.data.header.Count == taskErrorInfos.Count)
|
return JsonConvert.SerializeObject(new PutConveyorTaskResponse
|
{
|
Response = new PutConveyorTaskResponseData
|
{
|
Return = new PutConveyorTaskReturnInfo
|
{
|
returnCode = "0001",
|
returnDesc = "全部重复",
|
returnFlag = "0"
|
}
|
}
|
});
|
else
|
{
|
if (taskErrorInfos.Count == 0)
|
return JsonConvert.SerializeObject(new PutConveyorTaskResponse
|
{
|
Response = new PutConveyorTaskResponseData
|
{
|
Return = new PutConveyorTaskReturnInfo
|
{
|
returnCode = "0000",
|
returnFlag = "1"
|
}
|
}
|
});
|
else
|
{
|
return JsonConvert.SerializeObject(new PutConveyorTaskResponse
|
{
|
Response = new PutConveyorTaskResponseData
|
{
|
Return = new PutConveyorTaskReturnInfo
|
{
|
returnCode = "0001",
|
returnDesc = "部分重复",
|
returnFlag = "2",
|
resultInfo = taskErrorInfos
|
}
|
}
|
});
|
}
|
}
|
}
|
|
///上报称重尺寸 - websocket .这里写着作为记录
|
case "/api/Wcs/reportWeightinfo":
|
{
|
statusCode = System.Net.HttpStatusCode.OK;
|
if (/*list.Count > 0 && */WebSocketClientWithReconnect.GetWebSocketState() == WebSocketState.Open)
|
//for (int i = 60000; i < 70000; i++)
|
{
|
//Thread.Sleep(1000);
|
var req = new ReportWeightInfoRequest
|
{
|
data = new ReportWeightInfoData
|
{
|
header = new ReportWeightInfoHeader
|
{
|
deliveryNo = "F00001",
|
grossWeight = 99,
|
cube = 66,
|
addTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"),
|
addWho = "WCS"
|
}
|
}
|
};
|
//Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")}>>>GGG{i}");
|
LogHelper.Info(JsonConvert.SerializeObject(req));
|
var b = WebSocketClientWithReconnect.Instance?.SendAsync(JsonConvert.SerializeObject(req)).Result;
|
Console.WriteLine(req.data.header.deliveryNo + "发送完成!!" + b);
|
if (b == true)
|
{
|
// 等待特定响应
|
|
var rr = reportWeightinfo.GetChinnnl().Result;
|
|
LogHelper.Info("接收" + JsonConvert.SerializeObject(rr));
|
//}
|
return JsonConvert.SerializeObject(rr);
|
}
|
else return "发送失败。";
|
}
|
}
|
break;
|
}
|
break;
|
}
|
case "GET":
|
{
|
switch (path)
|
{
|
case var _ when System.Text.RegularExpressions.Regex.IsMatch(path, @"\.(html|ico|js|css)(\?.*)?$", System.Text.RegularExpressions.RegexOptions.IgnoreCase):
|
{
|
statusCode = System.Net.HttpStatusCode.OK;
|
// 复制到case 上
|
//var _ when System.Text.RegularExpressions.Regex.IsMatch(path, @"\.(html|ico|js|css)(\?.*)?$", System.Text.RegularExpressions.RegexOptions.IgnoreCase)
|
var filePath = /*Directory.GetCurrentDirectory() + "\\Static" + "\\" + path.Substring(1);*/System.IO.Path.Combine(Directory.GetCurrentDirectory() + "\\Static", path.Substring(1));
|
return File.ReadAllText(filePath);
|
}
|
}
|
break;
|
}
|
}
|
statusCode = System.Net.HttpStatusCode.NotFound;
|
return "";
|
}
|
catch (Exception ex)
|
{
|
Conn.log默认日志.Error(ex.ToString());
|
statusCode = System.Net.HttpStatusCode.InternalServerError;
|
return "";
|
}
|
}
|
}
|
|
class EnhancedWebSocketServer
|
{
|
private HttpListener _listener;
|
private readonly string _listenerPrefix;
|
private readonly ConcurrentDictionary<Guid, WebSocket> _connections = new ConcurrentDictionary<Guid, WebSocket>();
|
private CancellationTokenSource _cts = new CancellationTokenSource();
|
|
public EnhancedWebSocketServer(string url)
|
{
|
_listenerPrefix = url;
|
}
|
|
public async Task StartAsync()
|
{
|
try
|
{
|
_listener = new HttpListener();
|
_listener.Prefixes.Add(_listenerPrefix);
|
_listener.Start();
|
Console.WriteLine($"WebSocket服务器已启动,监听 {_listenerPrefix}");
|
while (!_cts.IsCancellationRequested)
|
{
|
HttpListenerContext context = await _listener.GetContextAsync();
|
if (context.Request.IsWebSocketRequest)
|
{
|
var wsContext = await context.AcceptWebSocketAsync(null);
|
var connectionId = Guid.NewGuid();
|
_connections[connectionId] = wsContext.WebSocket;
|
_ = HandleConnectionAsync(connectionId, wsContext.WebSocket, _cts.Token);
|
}
|
else
|
{
|
context.Response.StatusCode = 400;
|
context.Response.Close();
|
}
|
}
|
}
|
catch (Exception ex) when (ex is HttpListenerException || ex is ObjectDisposedException)
|
{
|
// 服务器停止时的正常异常
|
Console.WriteLine("服务器正在停止...");
|
}
|
}
|
|
private async Task HandleConnectionAsync(Guid connectionId, WebSocket webSocket, CancellationToken ct)
|
{
|
var buffer = new byte[1024 * 4];
|
try
|
{
|
while (webSocket.State == WebSocketState.Open && !ct.IsCancellationRequested)
|
{
|
var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), ct);
|
|
if (result.MessageType == WebSocketMessageType.Close)
|
{
|
await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "客户端关闭连接", ct);
|
break;
|
}
|
|
string message = System.Text.Encoding.UTF8.GetString(buffer, 0, result.Count);
|
Console.WriteLine($"连接 {connectionId} 收到消息: {message}");
|
|
// 广播消息给所有客户端
|
await BroadcastMessageAsync($"客户端 {connectionId} 说: {message}");
|
}
|
}
|
catch (WebSocketException ex)
|
{
|
Console.WriteLine($"连接 {connectionId} 错误: {ex.WebSocketErrorCode} - {ex.Message}");
|
}
|
catch (Exception ex)
|
{
|
Console.WriteLine($"处理连接 {connectionId} 时出错: {ex.Message}");
|
}
|
finally
|
{
|
_connections.TryRemove(connectionId, out _);
|
webSocket?.Dispose();
|
Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")} 连接 {connectionId} 已关闭");
|
}
|
}
|
|
public async Task BroadcastMessageAsync(string message)
|
{
|
var buffer = System.Text.Encoding.UTF8.GetBytes(message);
|
foreach (var connection in _connections)
|
{
|
if (connection.Value.State == WebSocketState.Open)
|
{
|
try
|
{
|
await connection.Value.SendAsync(
|
new ArraySegment<byte>(buffer),
|
WebSocketMessageType.Text,
|
true,
|
CancellationToken.None);
|
}
|
catch (Exception ex)
|
{
|
Console.WriteLine($"广播消息到连接 {connection.Key} 失败: {ex.Message}");
|
}
|
}
|
}
|
}
|
|
public async Task StopAsync()
|
{
|
_cts.Cancel();
|
|
// 关闭所有连接
|
foreach (var connection in _connections)
|
{
|
try
|
{
|
if (connection.Value.State == WebSocketState.Open)
|
{
|
await connection.Value.CloseAsync(
|
WebSocketCloseStatus.NormalClosure,
|
"服务器关闭",
|
CancellationToken.None);
|
}
|
connection.Value.Dispose();
|
}
|
catch (Exception ex)
|
{
|
Console.WriteLine($"关闭连接 {connection.Key} 时出错: {ex.Message}");
|
}
|
}
|
|
_listener?.Stop();
|
_listener?.Close();
|
Console.WriteLine("WebSocket服务器已停止");
|
}
|
|
}
|
|
public class WebSocketClientWithReconnect
|
{
|
//public static List<object> SendList = new List<object>();
|
|
public static ClientWebSocket _webSocket;
|
private static WebSocketClientWithReconnect _instance;
|
private readonly Uri _serverUri;
|
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
|
private readonly int _reconnectDelayMs;
|
|
public event Action<string> OnMessageReceived = msg => Console.WriteLine($"{DateTime.Now.ToString("HH:mm:ss.fff")}>>>Received: {msg}");
|
public event Action OnConnected = () => Console.WriteLine("Connected to server");
|
public event Action OnDisconnected = () => Console.WriteLine("Disconnected from webSocket server");
|
public event Action<Exception> OnError = ex => Console.WriteLine($"Error: {ex.Message}");
|
|
public WebSocketClientWithReconnect(string serverUrl, int reconnectDelayMs = 5000)
|
{
|
_serverUri = new Uri(serverUrl);
|
_reconnectDelayMs = reconnectDelayMs;
|
}
|
public static WebSocketClientWithReconnect Instance
|
{
|
get
|
{
|
return _instance;
|
}
|
}
|
|
public static WebSocketState GetWebSocketState() => _webSocket != null ? _webSocket.State : WebSocketState.Closed;
|
public async Task StartAsync()
|
{
|
_instance = this;
|
while (!_cts.IsCancellationRequested)
|
{
|
try
|
{
|
_webSocket = new ClientWebSocket();
|
await _webSocket.ConnectAsync(_serverUri, _cts.Token);
|
OnConnected?.Invoke();
|
await ReceiveMessagesAsync();
|
}
|
catch (Exception ex) when (!_cts.IsCancellationRequested)
|
{
|
OnError?.Invoke(ex);
|
await HandleDisconnection();
|
}
|
}
|
}
|
|
private async Task ReceiveMessagesAsync()
|
{
|
var buffer = new byte[1024 * 4];
|
|
while (_webSocket.State == WebSocketState.Open && !_cts.IsCancellationRequested)
|
{
|
try
|
{
|
var result = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), _cts.Token);
|
|
if (result.MessageType == WebSocketMessageType.Close)
|
{
|
await HandleDisconnection();
|
break;
|
}
|
|
var message = System.Text.Encoding.UTF8.GetString(buffer, 0, result.Count);
|
OnMessageReceived?.Invoke(message);
|
}
|
catch (Exception ex) when (!_cts.IsCancellationRequested)
|
{
|
OnError?.Invoke(ex);
|
await HandleDisconnection();
|
break;
|
}
|
}
|
}
|
|
private async Task HandleDisconnection()
|
{
|
OnDisconnected?.Invoke();
|
|
try
|
{
|
if (_webSocket != null && _webSocket.State != WebSocketState.Closed)
|
{
|
await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None);
|
_webSocket.Dispose();
|
}
|
}
|
catch { /* 忽略关闭时的异常 */ }
|
|
if (!_cts.IsCancellationRequested)
|
{
|
await Task.Delay(_reconnectDelayMs, _cts.Token);
|
}
|
}
|
|
public async Task StopAsync()
|
{
|
_cts.Cancel();
|
|
try
|
{
|
if (_webSocket != null && _webSocket.State == WebSocketState.Open)
|
{
|
await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Client shutdown", CancellationToken.None);
|
}
|
}
|
finally
|
{
|
_webSocket?.Dispose();
|
}
|
}
|
|
public async Task<bool> SendAsync(string message)
|
{
|
if (_webSocket?.State != WebSocketState.Open)
|
{
|
throw new InvalidOperationException("WebSocket is not connected");
|
}
|
|
var bytes = System.Text.Encoding.UTF8.GetBytes(message);
|
await _webSocket.SendAsync(new ArraySegment<byte>(bytes), WebSocketMessageType.Text, true, _cts.Token);
|
return true;
|
}
|
}
|
|
public class TcpServer
|
{
|
public static Dictionary<string, string> TrayIps = new Dictionary<string, string>();
|
public TcpServer(string ip)
|
{
|
Init(ip);
|
}
|
private void Init(string ip)
|
{
|
//创建一个新的Socket,这里我们使用最常用的基于TCP的Stream Socket(流式套接字)
|
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
try
|
{
|
//将该socket绑定到主机上面的某个端口
|
socket.Bind(new IPEndPoint(IPAddress.Parse(ip), 2025));
|
Console.WriteLine($"TCPServer socket 监听{ip}:{2025} ");
|
//启动监听,并且设置一个最大的队列长度
|
socket.Listen(30);
|
//开始接受客户端连接请求
|
socket.BeginAccept(new AsyncCallback(ClientAccepted), socket);
|
}
|
catch (Exception e)
|
{
|
Console.WriteLine(e.Message);
|
}
|
}
|
public static Dictionary<string, Socket> clients = new Dictionary<string, Socket>();
|
public static Dictionary<string, byte[]> buffers = new Dictionary<string, byte[]>();
|
public static void ClientAccepted(IAsyncResult ar)
|
{
|
|
var socket = ar.AsyncState as Socket;
|
var client = socket.EndAccept(ar);
|
string remote_ip = ((System.Net.IPEndPoint)client.RemoteEndPoint).Address.ToString();
|
if (clients.Keys.Contains(remote_ip))
|
{
|
clients[remote_ip] = client;
|
}
|
else
|
{
|
clients.Add(remote_ip, client);
|
}
|
if (!buffers.Keys.Contains(remote_ip))
|
{
|
buffers.Add(remote_ip, new byte[1024]);
|
}
|
//给客户端发送一个欢迎消息
|
//client.Send(Encoding.Unicode.GetBytes("Hi there, I accept you request at " + DateTime.Now.ToString()));
|
Console.WriteLine(remote_ip);
|
|
try
|
{
|
client.BeginReceive(buffers[remote_ip], 0, buffers[remote_ip].Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), client);
|
}
|
catch (Exception ex)
|
{
|
Console.WriteLine($"【接收客户端的消息异常0】:" + ex.Message);
|
}
|
//准备接受下一个客户端请求
|
socket.BeginAccept(new AsyncCallback(ClientAccepted), socket);
|
}
|
|
|
public static void ReceiveMessage(IAsyncResult ar)
|
{
|
try
|
{
|
var socket = ar.AsyncState as Socket;
|
string remote_ip = ((System.Net.IPEndPoint)socket.RemoteEndPoint).Address.ToString();
|
var length = socket.EndReceive(ar);
|
if (length == 0)
|
{
|
clients.Remove(remote_ip);
|
buffers.Remove(remote_ip);
|
return;
|
}
|
else
|
{
|
if (!clients.Keys.Contains(remote_ip))
|
{
|
clients.Add(remote_ip, socket);
|
}
|
if (!buffers.Keys.Contains(remote_ip))
|
{
|
buffers.Add(remote_ip, new byte[1024]);
|
}
|
}
|
try
|
{
|
if (buffers.Keys.Contains(remote_ip))
|
{
|
//读取出来消息内容
|
var message = GetHexString(buffers[remote_ip], length);
|
//16 10
|
// Console.WriteLine($"{DateTime.Now.ToString("hh:mm:ss")} ---> " + remote_ip + " : " + message);
|
//if (message.Substring(0, 4) == "3f00" && message.Substring(message.Length - 4) == "0d0a")
|
//{
|
// //显示消息
|
// //string msg = message.Replace(@"0d", "").Replace(@"0a", "").Replace(@"0d0a", "").Trim();
|
// //PlcHelper.Receive(remote_ip, msg);
|
// //Array.Clear(buffers[remote_ip], 0, buffers[remote_ip].Length);//清空当前IP Buffer
|
//}
|
//else
|
//{
|
Console.WriteLine($"【TCP信息协议 {DateTime.Now.Millisecond}】:IP:{remote_ip},MSG:{message}");
|
var mg = message;// Encoding.ASCII.GetString(PlcHelper.Hex2Bin(message));
|
if (mg.Length > 10)
|
{
|
mg = mg.Substring(0, 10);
|
}
|
Console.WriteLine(mg);
|
if (mg.StartsWith("DK"))//&& mg.Trim().Length == "DK01000024".Length
|
{
|
LogHelper.Info($"扫码器 >{remote_ip} -{mg}");
|
if (TrayIps.TryGetValue(remote_ip, out string traycode))
|
{
|
TrayIps[remote_ip] = mg;
|
}
|
else TrayIps.Add(remote_ip, mg);
|
|
RedisHelper.Add("S扫码器" + (remote_ip.Split('.').LastOrDefault()), mg, out string msg);
|
RedisHelper.Add("S扫码器" + (remote_ip.Split('.').LastOrDefault()) + "#time", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), out msg);
|
//Console.WriteLine("TOFF");
|
//var mst = PlcHelper.Hex2Bin("544F4646");
|
//TcpServer.TcpServerSend(remote_ip, mst);
|
}
|
//}
|
}
|
else
|
{
|
if (!buffers.Keys.Contains(remote_ip))
|
{
|
buffers.Add(remote_ip, new byte[1024]);
|
}
|
}
|
}
|
catch (Exception ex)
|
{
|
Console.WriteLine($"【处理客户端的消息异常2】:" + ex.StackTrace);
|
throw;
|
}
|
//接收下一个消息(因为这是一个递归的调用,所以这样就可以一直接收消息了)
|
socket.BeginReceive(buffers[remote_ip], 0, buffers[remote_ip].Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), socket);
|
}
|
catch (Exception ex)
|
{
|
Console.WriteLine(ex.Message);
|
}
|
}
|
|
private static string GetHexString(byte[] buffer, int lenght)
|
{
|
return BitConverter.ToString(buffer, 0, lenght).Replace("-", string.Empty).ToLower();
|
}
|
|
public static bool TcpServerSend(string ip, byte[] msg)
|
{
|
LogHelper.Info($"TcpServerSend >{ip}:{msg}");
|
if (clients.Keys.Contains(ip))
|
{
|
var client = clients[ip];
|
if (client.Connected)
|
{
|
try
|
{
|
client.Send(msg);
|
LogHelper.Info($"TcpServerSend > 发送成功。");
|
return true;
|
}
|
catch (SocketException ex)
|
{
|
Console.WriteLine(ex.Message);
|
clients[ip].Close();
|
clients.Remove(ip);
|
}
|
}
|
else
|
{
|
clients[ip].Close();
|
clients.Remove(ip);
|
}
|
}
|
else
|
{
|
Console.WriteLine("未找到设备的链接:" + ip);
|
}
|
return false;
|
|
}
|
|
public static int GetBitdata(int num, int wid)
|
{
|
string bstr = Convert.ToString(num, 2);
|
if (bstr.Length <= wid)
|
{
|
return 0;
|
}
|
return bstr[bstr.Length - wid - 1] - '0';
|
}
|
public static int SetBinaryDigit(int number, int n, int value)
|
{
|
if (value != 0 && value != 1)
|
throw new ArgumentException("Value must be 0 or 1.");
|
|
string binaryStr = Convert.ToString(number, 2);
|
|
// 如果 n 超出当前位数,补 0 扩展
|
while (binaryStr.Length <= n)
|
{
|
binaryStr = "0" + binaryStr;
|
}
|
|
// 修改第 n 位(从右往左,最低位是第 0 位)
|
char[] binaryChars = binaryStr.ToCharArray();
|
binaryChars[binaryChars.Length - 1 - n] = value == 1 ? '1' : '0';
|
|
// 转换回十进制
|
return Convert.ToInt32(new string(binaryChars), 2);
|
}
|
public static List<string> GetStaticClients() => clients.Keys.ToList();
|
public static Dictionary<string, string> GetStaticScan() => TrayIps;
|
}
|
|
public class LogHelper
|
{
|
#region [自定义类][20250323145442478][LogHelper]
|
public static Dictionary<string, ILogger> loggers = new Dictionary<string, ILogger>();
|
|
public static void Debug(string message, string name = "")
|
{
|
ILogger logger = null;
|
if (loggers.Keys.Contains(name))
|
{
|
logger = loggers[name];
|
}
|
else
|
{
|
logger = LogFactory.CreateLogger(name);
|
if (logger != null)
|
{
|
loggers.Add(name, logger);
|
}
|
else
|
{
|
logger = LogFactory.CreateLogger("console");
|
}
|
}
|
if (logger != null)
|
{
|
logger.Debug(message);
|
}
|
}
|
|
|
|
public static void Info(string message, string name = "")
|
{
|
//logger.Info(message);
|
ILogger logger = null;
|
if (loggers.Keys.Contains(name))
|
{
|
logger = loggers[name];
|
}
|
else
|
{
|
logger = LogFactory.CreateLogger(name);
|
if (logger != null && !loggers.Keys.Contains(name))
|
{
|
loggers.Add(name, logger);
|
}
|
else
|
{
|
logger = LogFactory.CreateLogger("infoFile");
|
}
|
}
|
if (logger != null)
|
{
|
logger.Info(message);
|
}
|
}
|
|
public static void Error(string message, Exception ex, string name = "")
|
{
|
//logger.Error(ex, message);
|
ILogger logger = null;
|
if (loggers.Keys.Contains(name))
|
{
|
logger = loggers[name];
|
}
|
else
|
{
|
logger = LogFactory.CreateLogger(name);
|
if (logger != null && !loggers.Keys.Contains(name))
|
{
|
loggers.Add(name, logger);
|
}
|
else
|
{
|
logger = LogFactory.CreateLogger("errorFile");
|
}
|
}
|
if (logger != null)
|
{
|
logger.Error($"{message}{ex.StackTrace}");
|
}
|
}
|
#endregion [自定义类][20250323145442478][LogHelper]
|
}
|
public class LogFactory
|
{
|
#region [自定义类][20250323145505759][LogFactory]
|
/// <summary>
|
/// 通过配置文件配置日志
|
/// </summary>
|
static LogFactory()
|
{
|
var loggerNames = new List<string>() { "HosttoagvTask", "HosttoagvCar", "NDC", "杭奥" };
|
LogManager.Configuration = DefaultConfig(loggerNames);
|
}
|
public static ILogger CreateLogger(string name)
|
{
|
var logger = LogManager.GetLogger(name);
|
return logger;
|
}
|
|
public static LoggingConfiguration DefaultConfig(List<string> loggerNames)
|
{
|
var config = new LoggingConfiguration();
|
loggerNames.ForEach(a =>
|
{
|
var target = new FileTarget();
|
target.ArchiveAboveSize = 1024 * 1024 * 5;//每个文件最大5M
|
target.ArchiveNumbering = ArchiveNumberingMode.DateAndSequence;
|
target.ArchiveFileName = @"${basedir}/Logs/" + a + "/{####}.txt";
|
target.FileName = @"${basedir}/Logs/" + a + "/${shortdate}.txt";//当前文件路径
|
target.Layout = @"${longdate} | ${level:uppercase=false:padding=-5} | ${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}";
|
|
config.AddTarget(a, target);
|
config.AddRuleForOneLevel(LogLevel.Info, target, a);
|
});
|
|
|
// 添加target-console
|
var consoleTarget = new ColoredConsoleTarget();
|
consoleTarget.Layout = @"${longdate} | ${level:uppercase=false:padding=-5} | ${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}";
|
|
config.AddTarget("console", consoleTarget);
|
config.AddRule(LogLevel.Debug, LogLevel.Fatal, consoleTarget);
|
|
//添加target-info
|
var infoFileTarget = new FileTarget();
|
infoFileTarget.ArchiveAboveSize = 1024 * 1024 * 5;//每个文件最大5M
|
infoFileTarget.ArchiveNumbering = ArchiveNumberingMode.DateAndSequence;
|
infoFileTarget.ArchiveFileName = @"${basedir}/Logs/Info/{####}.txt";
|
infoFileTarget.FileName = @"${basedir}/Logs/Info/${shortdate}.txt";//当前文件路径
|
infoFileTarget.Layout = @"${longdate} | ${level:uppercase=false:padding=-5} | ${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}";
|
|
config.AddTarget("infoFile", infoFileTarget);
|
config.AddRuleForOneLevel(LogLevel.Info, infoFileTarget);//INFO写在Info文件
|
|
//添加target-err
|
var errorFileTarget = new FileTarget();
|
errorFileTarget.ArchiveAboveSize = 1024 * 1024 * 5;//每个文件最大5M
|
errorFileTarget.ArchiveNumbering = ArchiveNumberingMode.DateAndSequence;
|
errorFileTarget.ArchiveFileName = @"${basedir}/Logs/Error/{####}.txt";
|
errorFileTarget.FileName = @"${basedir}/Logs/Error/${shortdate}.txt";
|
errorFileTarget.Layout = @"${longdate} | ${level:uppercase=false:padding=-5} | ${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}";
|
|
config.AddTarget("errorFile", errorFileTarget);
|
config.AddRule(LogLevel.Error, LogLevel.Fatal, errorFileTarget);
|
|
|
return config;
|
}
|
|
#endregion [自定义类][20250323145505759][LogFactory]
|
}
|
|
public class HttpHelper
|
{
|
#region [自定义类][20250325095622918][HttpHelper]
|
public string Post(string url, string postData, string contentType = "application/json", string sessionId = "")
|
{
|
LogHelper.Info(url + "+" + postData);
|
WebRequest request = WebRequest.Create(url);
|
request.Method = "POST";
|
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
|
request.ContentType = contentType;
|
request.ContentLength = byteArray.Length;
|
request.Timeout = 15000;
|
if (sessionId != "")
|
{
|
request.Headers.Set("ASP.NET_SessionId", sessionId);
|
}
|
|
//Authorization: UApGP6WW9FsBUqAlzxRGOw ==
|
request.Headers.Set("Authorization", "UApGP6WW9FsBUqAlzxRGOw==");
|
StreamReader reader = null;
|
Stream stream = null;
|
WebResponse rsp = null;
|
try
|
{
|
stream = request.GetRequestStream();
|
stream.Write(byteArray, 0, byteArray.Length);
|
stream.Close();
|
rsp = request.GetResponse();
|
stream = rsp.GetResponseStream();
|
reader = new StreamReader(stream);
|
string rrend = reader.ReadToEnd();
|
LogHelper.Info($"{url} response={rrend}");
|
return rrend;
|
}
|
catch (Exception ex)
|
{
|
LogHelper.Info($"{url} err={ex.Message}");
|
return "";
|
}
|
finally
|
{
|
// 释放资源
|
if (reader != null) reader.Close();
|
if (stream != null) stream.Close();
|
if (rsp != null) rsp.Close();
|
}
|
|
}
|
#endregion [自定义类][20250325095622918][HttpHelper]
|
}
|
public class Clloc
|
{
|
public class sendTask
|
{
|
/// <summary>
|
/// 任务下发请求
|
/// </summary>
|
public class SendTaskRequest
|
{
|
/// <summary>
|
/// 请求数据
|
/// </summary>
|
public SendTaskData data { get; set; }
|
}
|
|
public class SendTaskData
|
{
|
/// <summary>
|
/// 请求头信息
|
/// </summary>
|
public SendTaskHeader header { get; set; }
|
}
|
|
public class SendTaskHeader
|
{
|
/// <summary>
|
/// 组织编号 - 主键,默认MERCURY
|
/// </summary>
|
public string organizationId { get; set; } = "MERCURY";
|
|
/// <summary>
|
/// 仓库编号 - 主键,默认HN02
|
/// </summary>
|
public string warehouseId { get; set; } = "HN02";
|
|
/// <summary>
|
/// 任务组编号 - 主键
|
/// </summary>
|
public string groupTaskId { get; set; }
|
|
/// <summary>
|
/// 任务组序号 - 主键
|
/// </summary>
|
public int groupTaskSequence { get; set; }
|
|
/// <summary>
|
/// 托盘号
|
/// </summary>
|
public string palletId { get; set; }
|
|
/// <summary>
|
/// 来源库位
|
/// </summary>
|
public string fmLocation { get; set; }
|
|
/// <summary>
|
/// 来源点位
|
/// </summary>
|
public string fmPosition { get; set; }
|
|
/// <summary>
|
/// 目标库位号
|
/// </summary>
|
public string toLocation { get; set; }
|
|
/// <summary>
|
/// 目标点位
|
/// </summary>
|
public string toPosition { get; set; }
|
|
/// <summary>
|
/// 状态 - 00:创建
|
/// </summary>
|
public string taskStatus { get; set; } = "00";
|
|
/// <summary>
|
/// 任务类型 - PA:入库(上架/回库/移库), PK:出库(拣货/移库/补货/盘点), MV:倒库
|
/// </summary>
|
public string taskType { get; set; }
|
|
/// <summary>
|
/// 创建时间
|
/// </summary>
|
public DateTime addTime { get; set; }
|
|
/// <summary>
|
/// 创建人
|
/// </summary>
|
public string addWho { get; set; }
|
|
/// <summary>
|
/// 优先级 - 1-5(1最高,5最低),默认3
|
/// </summary>
|
public string priority { get; set; } = "3";
|
|
}
|
|
/// <summary>
|
/// 任务下发响应
|
/// </summary>
|
public class SendTaskResponse
|
{
|
public ResponseData Response { get; set; }
|
}
|
|
public class ResponseData
|
{
|
[JsonProperty("return")]
|
public ReturnInfo Return { get; set; }
|
}
|
|
public class ReturnInfo
|
{
|
/// <summary>
|
/// 返回代码 - 0000:成功, 其他:失败
|
/// </summary>
|
public string returnCode { get; set; }
|
|
/// <summary>
|
/// 返回描述
|
/// </summary>
|
public string returnDesc { get; set; }
|
|
/// <summary>
|
/// 返回标记 - 1:成功, 0:失败
|
/// </summary>
|
public string returnFlag { get; set; }
|
}
|
}
|
|
public class stockInException
|
{
|
/// <summary>
|
/// 入库异常请求
|
/// </summary>
|
public class StockInExceptionRequest
|
{
|
public StockInExceptionData data { get; set; }
|
}
|
|
public class StockInExceptionData
|
{
|
public StockInExceptionHeader header { get; set; }
|
}
|
|
public class StockInExceptionHeader
|
{
|
/// <summary>
|
/// 组织编号 - 主键,默认MERCURY
|
/// </summary>
|
public string organizationId { get; set; } = "MERCURY";
|
|
/// <summary>
|
/// 仓库编号 - 主键,默认HN02
|
/// </summary>
|
public string warehouseId { get; set; } = "HN02";
|
|
/// <summary>
|
/// 任务组编号 - 主键
|
/// </summary>
|
public string groupTaskId { get; set; }
|
|
/// <summary>
|
/// 任务组序号 - 主键
|
/// </summary>
|
public int groupTaskSequence { get; set; }
|
|
/// <summary>
|
/// 托盘号
|
/// </summary>
|
public string palletId { get; set; }
|
|
/// <summary>
|
/// 创建时间
|
/// </summary>
|
public string addTime { get; set; }
|
|
/// <summary>
|
/// 创建设备
|
/// </summary>
|
public string addWho { get; set; }
|
|
/// <summary>
|
/// 异常原因描述
|
/// </summary>
|
public string reason { get; set; }
|
|
/// <summary>
|
/// 异常原因代码 - 01:库位有货不可用, 03:入内伸位外伸位有货
|
/// </summary>
|
public string reasonCode { get; set; }
|
|
// ... UDF字段
|
}
|
|
/// <summary>
|
/// 入库异常响应
|
/// </summary>
|
public class StockInExceptionResponse
|
{
|
public StockInExceptionResponseData Response { get; set; }
|
}
|
|
public class StockInExceptionResponseData
|
{
|
[JsonProperty("return")]
|
public StockInExceptionReturnInfo Return { get; set; }
|
}
|
|
public class StockInExceptionReturnInfo : ReturnInfo
|
{
|
/// <summary>
|
/// 新分配的目标库位
|
/// </summary>
|
public string toLocation { get; set; }
|
|
/// <summary>
|
/// 新分配的目标点位
|
/// </summary>
|
public string toPosition { get; set; }
|
}
|
}
|
|
public class taskFeedback
|
{
|
/// <summary>
|
/// 任务反馈请求
|
/// </summary>
|
public class TaskFeedbackRequest
|
{
|
public TaskFeedbackData data { get; set; }
|
}
|
|
public class TaskFeedbackData
|
{
|
public TaskFeedbackHeader header { get; set; }
|
}
|
|
public class TaskFeedbackHeader
|
{
|
/// <summary>
|
/// 组织编号 - 主键,默认MERCURY
|
/// </summary>
|
public string organizationId { get; set; } = "MERCURY";
|
|
/// <summary>
|
/// 仓库编号 - 主键,默认HN02
|
/// </summary>
|
public string warehouseId { get; set; } = "HN02";
|
|
/// <summary>
|
/// 任务组编号 - 主键
|
/// </summary>
|
public string groupTaskId { get; set; }
|
|
/// <summary>
|
/// 任务组序号 - 主键
|
/// </summary>
|
public int groupTaskSequence { get; set; }
|
|
/// <summary>
|
/// 托盘号
|
/// </summary>
|
public string palletId { get; set; }
|
|
/// <summary>
|
/// 来源库位
|
/// </summary>
|
public string fmLocation { get; set; }
|
|
/// <summary>
|
/// 来源点位
|
/// </summary>
|
public string fmPosition { get; set; }
|
|
/// <summary>
|
/// 目标库位号
|
/// </summary>
|
public string toLocation { get; set; }
|
|
/// <summary>
|
/// 目标点位
|
/// </summary>
|
public string toPosition { get; set; }
|
|
/// <summary>
|
/// 状态 - 80:完成, 98:异常(取货无货)
|
/// </summary>
|
public string taskStatus { get; set; }
|
|
/// <summary>
|
/// 任务类型 - PA:入库, PK:出库, MV:倒库
|
/// </summary>
|
public string taskType { get; set; }
|
|
/// <summary>
|
/// 完成时间
|
/// </summary>
|
public string closeTime { get; set; }
|
|
/// <summary>
|
/// 完成人员
|
/// </summary>
|
public string closeWho { get; set; }
|
|
// ... UDF字段
|
}
|
}
|
public class stockInInteraction
|
{
|
/// <summary>
|
/// 入库交互请求
|
/// </summary>
|
public class StockInInteractionRequest
|
{
|
public StockInInteractionData data { get; set; }
|
}
|
|
public class StockInInteractionData
|
{
|
public StockInInteractionHeader header { get; set; }
|
}
|
|
public class StockInInteractionHeader
|
{
|
/// <summary>
|
/// 组织编号 - 主键,默认MERCURY
|
/// </summary>
|
public string organizationId { get; set; } = "MERCURY";
|
|
/// <summary>
|
/// 仓库编号 - 主键,默认HN02
|
/// </summary>
|
public string warehouseId { get; set; } = "HN02";
|
|
/// <summary>
|
/// 托盘号 - 主键
|
/// </summary>
|
public string palletId { get; set; }
|
|
/// <summary>
|
/// 总重量(kg)
|
/// </summary>
|
public decimal grossWeight { get; set; }
|
|
/// <summary>
|
/// 码盘宽度(cm)
|
/// </summary>
|
public decimal palletWidth { get; set; }
|
|
/// <summary>
|
/// 来源库位
|
/// </summary>
|
public string fmLocation { get; set; }
|
|
/// <summary>
|
/// 来源点位
|
/// </summary>
|
public string fmPosition { get; set; }
|
|
/// <summary>
|
/// 创建时间
|
/// </summary>
|
public DateTime addTime { get; set; }
|
|
/// <summary>
|
/// 创建人
|
/// </summary>
|
public string addWho { get; set; }
|
|
// ... UDF01-UDF10
|
}
|
|
/// <summary>
|
/// 入库交互响应
|
/// </summary>
|
public class StockInInteractionResponse
|
{
|
public StockInInteractionResponseData Response { get; set; }
|
}
|
|
public class StockInInteractionResponseData
|
{
|
[JsonProperty("return")]
|
public StockInInteractionReturnInfo Return { get; set; }
|
}
|
|
public class StockInInteractionReturnInfo : ReturnInfo
|
{
|
/// <summary>
|
/// 任务组编号
|
/// </summary>
|
public string groupTaskId { get; set; }
|
|
/// <summary>
|
/// 任务组序号
|
/// </summary>
|
public int groupTaskSequence { get; set; }
|
|
/// <summary>
|
/// 状态 - 00:创建
|
/// </summary>
|
public string taskStatus { get; set; }
|
|
/// <summary>
|
/// 任务类型 - PA:入库
|
/// </summary>
|
public string taskType { get; set; }
|
|
/// <summary>
|
/// 优先级 - 1-5(1最高)
|
/// </summary>
|
public string priority { get; set; }
|
|
/// <summary>
|
/// 目标库位号
|
/// </summary>
|
public string toLocation { get; set; }
|
|
/// <summary>
|
/// 目标点位
|
/// </summary>
|
public string toPosition { get; set; }
|
}
|
}
|
public class cancelTask
|
{
|
/// <summary>
|
/// 任务取消请求
|
/// </summary>
|
public class CancelTaskRequest
|
{
|
public CancelTaskData data { get; set; }
|
}
|
|
public class CancelTaskData
|
{
|
public CancelTaskHeader header { get; set; }
|
}
|
|
public class CancelTaskHeader
|
{
|
/// <summary>
|
/// 组织编号 - 主键,默认MERCURY
|
/// </summary>
|
public string organizationId { get; set; } = "MERCURY";
|
|
/// <summary>
|
/// 仓库编号 - 主键,默认HN02
|
/// </summary>
|
public string warehouseId { get; set; } = "HN02";
|
|
/// <summary>
|
/// 任务组编号 - 主键
|
/// </summary>
|
public string groupTaskId { get; set; }
|
|
/// <summary>
|
/// 任务组序号 - 主键
|
/// </summary>
|
public int groupTaskSequence { get; set; }
|
}
|
|
/// <summary>
|
/// 任务取消响应
|
/// </summary>
|
public class CancelTaskResponse
|
{
|
public ResponseData Response { get; set; }
|
}
|
}
|
public class palletStackerInteraction
|
{
|
/// <summary>
|
/// 叠盘机交互请求
|
/// </summary>
|
public class PalletStackerInteractionRequest
|
{
|
public PalletStackerInteractionData data { get; set; }
|
}
|
|
public class PalletStackerInteractionData
|
{
|
public PalletStackerInteractionHeader header { get; set; }
|
}
|
|
public class PalletStackerInteractionHeader
|
{
|
/// <summary>
|
/// 组织编号 - 主键,默认MERCURY
|
/// </summary>
|
public string organizationId { get; set; } = "MERCURY";
|
|
/// <summary>
|
/// 仓库编号 - 主键,默认HN02
|
/// </summary>
|
public string warehouseId { get; set; } = "HN02";
|
|
/// <summary>
|
/// 任务编号 - 主键,设备发出的请求ID
|
/// </summary>
|
public string taskId { get; set; }
|
|
/// <summary>
|
/// 托盘号
|
/// </summary>
|
public string palletId { get; set; }
|
|
/// <summary>
|
/// 类型 - PI:入库, PT:出库(当前无出库场景)
|
/// </summary>
|
public string taskType { get; set; }
|
|
/// <summary>
|
/// 起始库位 - 叠盘机物理起始位置
|
/// </summary>
|
public string fmLocation { get; set; }
|
|
/// <summary>
|
/// 优先级 - 1-5(1最高)
|
/// </summary>
|
public string priority { get; set; } = "3";
|
|
/// <summary>
|
/// 创建时间
|
/// </summary>
|
public string addTime { get; set; }
|
|
/// <summary>
|
/// 创建设备
|
/// </summary>
|
public string addWho { get; set; }
|
|
// ... UDF01-UDF10
|
}
|
|
/// <summary>
|
/// 叠盘机交互响应
|
/// </summary>
|
public class PalletStackerInteractionResponse
|
{
|
public ResponseData Response { get; set; }
|
}
|
|
}
|
public class modifyTaskPriority
|
{
|
/// <summary>
|
/// 修改任务优先级请求
|
/// </summary>
|
public class ModifyTaskPriorityRequest
|
{
|
public ModifyTaskPriorityData data { get; set; }
|
}
|
|
public class ModifyTaskPriorityData
|
{
|
public List<ModifyTaskPriorityHeader> header { get; set; }
|
}
|
|
public class ModifyTaskPriorityHeader
|
{
|
/// <summary>
|
/// 组织编号 - 主键,默认MERCURY
|
/// </summary>
|
public string organizationId { get; set; } = "MERCURY";
|
|
/// <summary>
|
/// 仓库编号 - 主键,默认HN02
|
/// </summary>
|
public string warehouseId { get; set; } = "HN02";
|
|
/// <summary>
|
/// 任务组编号 - 主键
|
/// </summary>
|
public string groupTaskId { get; set; }
|
|
/// <summary>
|
/// 任务组序号 - 主键
|
/// </summary>
|
public int groupTaskSequence { get; set; }
|
|
/// <summary>
|
/// 优先级 - 1-5(1最高)
|
/// </summary>
|
public string priority { get; set; }
|
}
|
|
/// <summary>
|
/// 修改任务优先级响应(支持部分成功)
|
/// </summary>
|
public class ModifyTaskPriorityResponse
|
{
|
public ModifyTaskPriorityResponseData Response { get; set; }
|
}
|
|
public class ModifyTaskPriorityResponseData
|
{
|
[JsonProperty("return")]
|
public ModifyTaskPriorityReturnInfo Return { get; set; }
|
}
|
|
public class ModifyTaskPriorityReturnInfo : ReturnInfo
|
{
|
/// <summary>
|
/// 部分成功时的错误详情
|
/// </summary>
|
public List<TaskErrorInfo> resultInfo { get; set; }
|
}
|
|
public class TaskErrorInfo
|
{
|
/// <summary>
|
/// 任务组编号
|
/// </summary>
|
public string groupTaskId { get; set; }
|
|
/// <summary>
|
/// 任务组序号
|
/// </summary>
|
public int groupTaskSequence { get; set; }
|
|
/// <summary>
|
/// 错误代码
|
/// </summary>
|
public string errorCode { get; set; }
|
|
/// <summary>
|
/// 错误原因
|
/// </summary>
|
public string errorDesc { get; set; }
|
}
|
}
|
public class putConveyorTask
|
{
|
/// <summary>
|
/// 输送线任务推送请求
|
/// </summary>
|
public class PutConveyorTaskRequest
|
{
|
public PutConveyorTaskData data { get; set; }
|
}
|
|
public class PutConveyorTaskData
|
{
|
public List<PutConveyorTaskHeader> header { get; set; }
|
}
|
|
public class PutConveyorTaskHeader
|
{
|
/// <summary>
|
/// 组织编号 - 主键,默认MERCURY
|
/// </summary>
|
public string organizationId { get; set; } = "MERCURY";
|
|
/// <summary>
|
/// 仓库编号 - 主键,默认HN02
|
/// </summary>
|
public string warehouseId { get; set; } = "HN02";
|
|
/// <summary>
|
/// 任务组编号 - 主键
|
/// </summary>
|
public string groupTaskId { get; set; }
|
|
/// <summary>
|
/// 任务组序号 - 主键
|
/// </summary>
|
public int groupTaskSequence { get; set; }
|
|
/// <summary>
|
/// 箱号
|
/// </summary>
|
public string palletId { get; set; }
|
|
/// <summary>
|
/// 箱型 - 大箱/小箱/周转箱编码
|
/// </summary>
|
public string palletIdType { get; set; }
|
|
/// <summary>
|
/// 贴标标记 - Y:需要贴标, N:不需要
|
/// </summary>
|
public string syncFlag { get; set; }
|
|
/// <summary>
|
/// 目标区域/道口 - 物理位置道口编码或B2C复核台区域编码
|
/// </summary>
|
public string dLocation { get; set; }
|
|
// ... UDF01-UDF10
|
}
|
|
/// <summary>
|
/// 输送线任务推送响应(支持部分成功)
|
/// </summary>
|
public class PutConveyorTaskResponse
|
{
|
public PutConveyorTaskResponseData Response { get; set; }
|
}
|
|
public class PutConveyorTaskResponseData
|
{
|
[JsonProperty("return")]
|
public PutConveyorTaskReturnInfo Return { get; set; }
|
}
|
|
public class PutConveyorTaskReturnInfo : ReturnInfo
|
{
|
/// <summary>
|
/// 部分成功时的错误详情
|
/// </summary>
|
public List<TaskErrorInfo> resultInfo { get; set; }
|
}
|
}
|
public class reportWeightinfo
|
{
|
public static Channel<ReportWeightInfoResponse> channel = Channel.CreateUnbounded<ReportWeightInfoResponse>();
|
|
internal static async Task<ReportWeightInfoReturnInfo> GetChinnnl()
|
{
|
//var response = await reportWeightinfo.channel.Reader.ReadAllAsync();// foreach (var response in reportWeightinfo.channel.Reader.ReadAllAsync())
|
//{
|
// return response?.Response?.Return ?? new ReportWeightInfoReturnInfo { ReturnCode = "0001", SortingChute = "0", ReturnDesc = "返回为空。" };
|
//}
|
while (await reportWeightinfo.channel.Reader.WaitToReadAsync(CancellationToken.None))
|
{
|
while (reportWeightinfo.channel.Reader.TryRead(out var response))
|
{
|
return response?.Response?.Return ?? new ReportWeightInfoReturnInfo { returnCode = "0001", sortingChute = "0", returnDesc = "返回为空。" };
|
}
|
}
|
return new ReportWeightInfoReturnInfo { returnCode = "0001", sortingChute = "0", returnDesc = "返回为空。" };
|
}
|
|
/// <summary>
|
/// 上报称重信息请求
|
/// </summary>
|
public class ReportWeightInfoRequest
|
{
|
public ReportWeightInfoData data { get; set; }
|
}
|
|
public class ReportWeightInfoData
|
{
|
public ReportWeightInfoHeader header { get; set; }
|
}
|
|
public class ReportWeightInfoHeader
|
{
|
/// <summary>
|
/// 组织编号 - 主键,默认MERCURY
|
/// </summary>
|
public string organizationId { get; set; } = "MERCURY";
|
|
/// <summary>
|
/// 仓库编号 - 主键,默认HN02
|
/// </summary>
|
public string warehouseId { get; set; } = "HN02";
|
|
/// <summary>
|
/// 面单号 - 主键
|
/// </summary>
|
public string deliveryNo { get; set; }
|
|
/// <summary>
|
/// 重量(kg)
|
/// </summary>
|
public decimal grossWeight { get; set; }
|
|
/// <summary>
|
/// 体积(立方厘米)
|
/// </summary>
|
public decimal cube { get; set; }
|
|
/// <summary>
|
/// 创建时间
|
/// </summary>
|
public string addTime { get; set; }
|
|
/// <summary>
|
/// 创建设备
|
/// </summary>
|
public string addWho { get; set; }
|
|
// ... UDF字段
|
}
|
|
/// <summary>
|
/// 上报称重信息响应
|
/// </summary>
|
public class ReportWeightInfoResponse
|
{
|
public ReportWeightInfoResponseData Response { get; set; }
|
}
|
|
public class ReportWeightInfoResponseData
|
{
|
[JsonProperty("return")]
|
public ReportWeightInfoReturnInfo Return { get; set; }
|
}
|
|
public class ReportWeightInfoReturnInfo : ReturnInfo
|
{
|
/// <summary>
|
/// 分拣道口 - 输送线快速分拣道口编码
|
/// </summary>
|
public string sortingChute { get; set; }
|
}
|
}
|
|
}
|
}
|
#endregion [自定义类-VS][20250701112200484][AutoThread]
|