#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 _methodCache = new ConcurrentDictionary(); // 方法执行器 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()); } } /// /// 配置初始化。 /// /// /// 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(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 lstr = new List(); public static List putConveyorTasks = new List(); 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(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(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 { "", "" }) { 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(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(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(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(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(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(requestJson); List taskErrorInfos = new List(); 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" } } }); 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(requestJson); List taskErrorInfos = new List(); 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 _connections = new ConcurrentDictionary(); 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(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(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 SendList = new List(); 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 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 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(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 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(bytes), WebSocketMessageType.Text, true, _cts.Token); return true; } } public class TcpServer { public static Dictionary TrayIps = new Dictionary(); 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 clients = new Dictionary(); public static Dictionary buffers = new Dictionary(); 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 GetStaticClients() => clients.Keys.ToList(); public static Dictionary GetStaticScan() => TrayIps; } public class LogHelper { #region [自定义类][20250323145442478][LogHelper] public static Dictionary loggers = new Dictionary(); 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] /// /// 通过配置文件配置日志 /// static LogFactory() { var loggerNames = new List() { "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 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 { /// /// 任务下发请求 /// public class SendTaskRequest { /// /// 请求数据 /// public SendTaskData data { get; set; } } public class SendTaskData { /// /// 请求头信息 /// public SendTaskHeader header { get; set; } } public class SendTaskHeader { /// /// 组织编号 - 主键,默认MERCURY /// public string organizationId { get; set; } = "MERCURY"; /// /// 仓库编号 - 主键,默认HN02 /// public string warehouseId { get; set; } = "HN02"; /// /// 任务组编号 - 主键 /// public string groupTaskId { get; set; } /// /// 任务组序号 - 主键 /// public int groupTaskSequence { get; set; } /// /// 托盘号 /// public string palletId { get; set; } /// /// 来源库位 /// public string fmLocation { get; set; } /// /// 来源点位 /// public string fmPosition { get; set; } /// /// 目标库位号 /// public string toLocation { get; set; } /// /// 目标点位 /// public string toPosition { get; set; } /// /// 状态 - 00:创建 /// public string taskStatus { get; set; } = "00"; /// /// 任务类型 - PA:入库(上架/回库/移库), PK:出库(拣货/移库/补货/盘点), MV:倒库 /// public string taskType { get; set; } /// /// 创建时间 /// public DateTime addTime { get; set; } /// /// 创建人 /// public string addWho { get; set; } /// /// 优先级 - 1-5(1最高,5最低),默认3 /// public string priority { get; set; } = "3"; } /// /// 任务下发响应 /// public class SendTaskResponse { public ResponseData Response { get; set; } } public class ResponseData { public ReturnInfo Return { get; set; } } public class ReturnInfo { /// /// 返回代码 - 0000:成功, 其他:失败 /// public string returnCode { get; set; } /// /// 返回描述 /// public string returnDesc { get; set; } /// /// 返回标记 - 1:成功, 0:失败 /// public string returnFlag { get; set; } } } public class stockInException { /// /// 入库异常请求 /// public class StockInExceptionRequest { public StockInExceptionData data { get; set; } } public class StockInExceptionData { public StockInExceptionHeader header { get; set; } } public class StockInExceptionHeader { /// /// 组织编号 - 主键,默认MERCURY /// public string organizationId { get; set; } = "MERCURY"; /// /// 仓库编号 - 主键,默认HN02 /// public string warehouseId { get; set; } = "HN02"; /// /// 任务组编号 - 主键 /// public string groupTaskId { get; set; } /// /// 任务组序号 - 主键 /// public int groupTaskSequence { get; set; } /// /// 托盘号 /// public string palletId { get; set; } /// /// 创建时间 /// public string addTime { get; set; } /// /// 创建设备 /// public string addWho { get; set; } /// /// 异常原因描述 /// public string reason { get; set; } /// /// 异常原因代码 - 01:库位有货不可用, 03:入内伸位外伸位有货 /// public string reasonCode { get; set; } // ... UDF字段 } /// /// 入库异常响应 /// public class StockInExceptionResponse { public StockInExceptionResponseData Response { get; set; } } public class StockInExceptionResponseData { public StockInExceptionReturnInfo Return { get; set; } } public class StockInExceptionReturnInfo : ReturnInfo { /// /// 新分配的目标库位 /// public string toLocation { get; set; } /// /// 新分配的目标点位 /// public string toPosition { get; set; } } } public class taskFeedback { /// /// 任务反馈请求 /// public class TaskFeedbackRequest { public TaskFeedbackData data { get; set; } } public class TaskFeedbackData { public TaskFeedbackHeader header { get; set; } } public class TaskFeedbackHeader { /// /// 组织编号 - 主键,默认MERCURY /// public string organizationId { get; set; } = "MERCURY"; /// /// 仓库编号 - 主键,默认HN02 /// public string warehouseId { get; set; } = "HN02"; /// /// 任务组编号 - 主键 /// public string groupTaskId { get; set; } /// /// 任务组序号 - 主键 /// public int groupTaskSequence { get; set; } /// /// 托盘号 /// public string palletId { get; set; } /// /// 来源库位 /// public string fmLocation { get; set; } /// /// 来源点位 /// public string fmPosition { get; set; } /// /// 目标库位号 /// public string toLocation { get; set; } /// /// 目标点位 /// public string toPosition { get; set; } /// /// 状态 - 80:完成, 98:异常(取货无货) /// public string taskStatus { get; set; } /// /// 任务类型 - PA:入库, PK:出库, MV:倒库 /// public string taskType { get; set; } /// /// 完成时间 /// public string closeTime { get; set; } /// /// 完成人员 /// public string closeWho { get; set; } // ... UDF字段 } } public class stockInInteraction { /// /// 入库交互请求 /// public class StockInInteractionRequest { public StockInInteractionData data { get; set; } } public class StockInInteractionData { public StockInInteractionHeader header { get; set; } } public class StockInInteractionHeader { /// /// 组织编号 - 主键,默认MERCURY /// public string organizationId { get; set; } = "MERCURY"; /// /// 仓库编号 - 主键,默认HN02 /// public string warehouseId { get; set; } = "HN02"; /// /// 托盘号 - 主键 /// public string palletId { get; set; } /// /// 总重量(kg) /// public decimal grossWeight { get; set; } /// /// 码盘宽度(cm) /// public decimal palletWidth { get; set; } /// /// 来源库位 /// public string fmLocation { get; set; } /// /// 来源点位 /// public string fmPosition { get; set; } /// /// 创建时间 /// public DateTime addTime { get; set; } /// /// 创建人 /// public string addWho { get; set; } // ... UDF01-UDF10 } /// /// 入库交互响应 /// public class StockInInteractionResponse { public StockInInteractionResponseData Response { get; set; } } public class StockInInteractionResponseData { public StockInInteractionReturnInfo Return { get; set; } } public class StockInInteractionReturnInfo : ReturnInfo { /// /// 任务组编号 /// public string groupTaskId { get; set; } /// /// 任务组序号 /// public int groupTaskSequence { get; set; } /// /// 状态 - 00:创建 /// public string taskStatus { get; set; } /// /// 任务类型 - PA:入库 /// public string taskType { get; set; } /// /// 优先级 - 1-5(1最高) /// public string priority { get; set; } /// /// 目标库位号 /// public string toLocation { get; set; } /// /// 目标点位 /// public string toPosition { get; set; } } } public class cancelTask { /// /// 任务取消请求 /// public class CancelTaskRequest { public CancelTaskData data { get; set; } } public class CancelTaskData { public CancelTaskHeader header { get; set; } } public class CancelTaskHeader { /// /// 组织编号 - 主键,默认MERCURY /// public string organizationId { get; set; } = "MERCURY"; /// /// 仓库编号 - 主键,默认HN02 /// public string warehouseId { get; set; } = "HN02"; /// /// 任务组编号 - 主键 /// public string groupTaskId { get; set; } /// /// 任务组序号 - 主键 /// public int groupTaskSequence { get; set; } } /// /// 任务取消响应 /// public class CancelTaskResponse { public ResponseData Response { get; set; } } } public class palletStackerInteraction { /// /// 叠盘机交互请求 /// public class PalletStackerInteractionRequest { public PalletStackerInteractionData data { get; set; } } public class PalletStackerInteractionData { public PalletStackerInteractionHeader header { get; set; } } public class PalletStackerInteractionHeader { /// /// 组织编号 - 主键,默认MERCURY /// public string organizationId { get; set; } = "MERCURY"; /// /// 仓库编号 - 主键,默认HN02 /// public string warehouseId { get; set; } = "HN02"; /// /// 任务编号 - 主键,设备发出的请求ID /// public string taskId { get; set; } /// /// 托盘号 /// public string palletId { get; set; } /// /// 类型 - PI:入库, PT:出库(当前无出库场景) /// public string taskType { get; set; } /// /// 起始库位 - 叠盘机物理起始位置 /// public string fmLocation { get; set; } /// /// 优先级 - 1-5(1最高) /// public string priority { get; set; } = "3"; /// /// 创建时间 /// public string addTime { get; set; } /// /// 创建设备 /// public string addWho { get; set; } // ... UDF01-UDF10 } /// /// 叠盘机交互响应 /// public class PalletStackerInteractionResponse { public ResponseData Response { get; set; } } } public class modifyTaskPriority { /// /// 修改任务优先级请求 /// public class ModifyTaskPriorityRequest { public ModifyTaskPriorityData data { get; set; } } public class ModifyTaskPriorityData { public List header { get; set; } } public class ModifyTaskPriorityHeader { /// /// 组织编号 - 主键,默认MERCURY /// public string organizationId { get; set; } = "MERCURY"; /// /// 仓库编号 - 主键,默认HN02 /// public string warehouseId { get; set; } = "HN02"; /// /// 任务组编号 - 主键 /// public string groupTaskId { get; set; } /// /// 任务组序号 - 主键 /// public int groupTaskSequence { get; set; } /// /// 优先级 - 1-5(1最高) /// public string priority { get; set; } } /// /// 修改任务优先级响应(支持部分成功) /// public class ModifyTaskPriorityResponse { public ModifyTaskPriorityResponseData Response { get; set; } } public class ModifyTaskPriorityResponseData { [JsonProperty("return")] public ModifyTaskPriorityReturnInfo Return { get; set; } } public class ModifyTaskPriorityReturnInfo : ReturnInfo { /// /// 部分成功时的错误详情 /// public List resultInfo { get; set; } } public class TaskErrorInfo { /// /// 任务组编号 /// public string groupTaskId { get; set; } /// /// 任务组序号 /// public int groupTaskSequence { get; set; } /// /// 错误代码 /// public string errorCode { get; set; } /// /// 错误原因 /// public string errorDesc { get; set; } } } public class putConveyorTask { /// /// 输送线任务推送请求 /// public class PutConveyorTaskRequest { public PutConveyorTaskData data { get; set; } } public class PutConveyorTaskData { public List header { get; set; } } public class PutConveyorTaskHeader { /// /// 组织编号 - 主键,默认MERCURY /// public string organizationId { get; set; } = "MERCURY"; /// /// 仓库编号 - 主键,默认HN02 /// public string warehouseId { get; set; } = "HN02"; /// /// 任务组编号 - 主键 /// public string groupTaskId { get; set; } /// /// 任务组序号 - 主键 /// public int groupTaskSequence { get; set; } /// /// 箱号 /// public string palletId { get; set; } /// /// 箱型 - 大箱/小箱/周转箱编码 /// public string palletIdType { get; set; } /// /// 贴标标记 - Y:需要贴标, N:不需要 /// public string syncFlag { get; set; } /// /// 目标区域/道口 - 物理位置道口编码或B2C复核台区域编码 /// public string dLocation { get; set; } // ... UDF01-UDF10 } /// /// 输送线任务推送响应(支持部分成功) /// public class PutConveyorTaskResponse { public PutConveyorTaskResponseData Response { get; set; } } public class PutConveyorTaskResponseData { public PutConveyorTaskReturnInfo Return { get; set; } } public class PutConveyorTaskReturnInfo : ReturnInfo { /// /// 部分成功时的错误详情 /// public List resultInfo { get; set; } } } public class reportWeightinfo { public static Channel channel = Channel.CreateUnbounded(); internal static async Task 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 = "返回为空。" }; } /// /// 上报称重信息请求 /// public class ReportWeightInfoRequest { public ReportWeightInfoData data { get; set; } } public class ReportWeightInfoData { public ReportWeightInfoHeader header { get; set; } } public class ReportWeightInfoHeader { /// /// 组织编号 - 主键,默认MERCURY /// public string organizationId { get; set; } = "MERCURY"; /// /// 仓库编号 - 主键,默认HN02 /// public string warehouseId { get; set; } = "HN02"; /// /// 面单号 - 主键 /// public string deliveryNo { get; set; } /// /// 重量(kg) /// public decimal grossWeight { get; set; } /// /// 体积(立方厘米) /// public decimal cube { get; set; } /// /// 创建时间 /// public string addTime { get; set; } /// /// 创建设备 /// public string addWho { get; set; } // ... UDF字段 } /// /// 上报称重信息响应 /// public class ReportWeightInfoResponse { public ReportWeightInfoResponseData Response { get; set; } } public class ReportWeightInfoResponseData { public ReportWeightInfoReturnInfo Return { get; set; } } public class ReportWeightInfoReturnInfo : ReturnInfo { /// /// 分拣道口 - 输送线快速分拣道口编码 /// public string sortingChute { get; set; } } } } } #endregion [自定义类-VS][20250701112200484][AutoThread]