schangxiang@126.com
2025-11-04 f5ed29dc26c7cd952d56ec5721a2efc43cd25992
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
 
using Newtonsoft.Json.Linq;
using Sodao.FastSocket.Server.Messaging;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using BiosenSocketService.Exceptions;
using XImaging.Automation.Library.HxDriverLib;
using XImaging.Automation.Service;
using XImaging.Automation.Service.Instruction;
using Sodao.FastSocket.SocketBase.Utils;
using System.Xml.Linq;
 
namespace XImaging.Automation.Service.Instruction
{
    public delegate void TroubleShootDelegate();
    public delegate void OnTaskFinishDelegate(TaskInstruction tIns, JObject data, int status);
    public delegate void OnTaskAbortDelegate(TaskInstruction tIns, string errCode, string errString);
    public delegate void QueryDataDelegate(JObject data);
    /*
     * HxTroubleShoot
     * 记录并处理任务指令中途错误的类
     */
    public class HxTroubleShoot
    {
        public const int TS_Ignore = 1;    // 错误处理方式:忽略
        public const int TS_Retry = 2;    // 错误处理方式:重试
        public const int TS_Abort = 4;    // 错误处理方式:中断 
 
        private string str_errCode;        // 错误码
        private int p_Troubleshoot=7;   // 可能的错误处理方式,0-7
        private string str_Message;   // 错误信息
        private int nDealwithtype = 0;
 
        public event TroubleShootDelegate IgnoreTrigger;   // Ignore事件
        public event TroubleShootDelegate RetryTrigger;    // Retry事件
        public event TroubleShootDelegate AbortTrigger;    // Abort事件
 
        private bool b_onWaiting = false;
        private int r_Troubleshoot = -1;  // 用户反馈的错误处理方式
 
        /// <summary>
        /// 记录新错误的信息
        /// </summary>
        /// <param name="errCode">错误码</param>
        /// <param name="TroubleshootPossibility">可行的处理方式</param>
        /// <param name="message">错误信息</param>
        public void Error(HxMessage hxMessage, string errCode, int TroubleshootPossibility, string MsgText, int nDealwithtype)
        {
            //while (b_onWaiting)
            //{
            //    Thread.Sleep(1000);
            //}
            this.str_errCode = errCode;
            this.p_Troubleshoot = TroubleshootPossibility;
            this.str_Message = MsgText;
            this.nDealwithtype = nDealwithtype;
 
            JObject err = JObject.FromObject(
               new
               {
                   error_code = str_errCode,
                   error_text = str_Message,
                   troubleshoot = p_Troubleshoot,
                   dealwithtype= nDealwithtype,
               }
           );
            HxTcpHandler.ReplyErrorMessage(hxMessage, err , str_errCode, str_Message, nDealwithtype, p_Troubleshoot);
        }
 
        /// <summary>
        /// 记录新错误的信息
        /// </summary>
        /// <param name="errCode">错误码</param>
        /// <param name="TroubleshootPossibility">可行的处理方式</param>
        /// <param name="message">错误信息</param>
        public void Abort(HxMessage hxMessage, string errCode, int TroubleshootPossibility, string MsgText, int nDealwithtype)
        {
            while (b_onWaiting)
            {
                Thread.Sleep(1000);
            }
            this.str_errCode = errCode;
            this.p_Troubleshoot = TroubleshootPossibility;
            this.str_Message = MsgText;
            this.nDealwithtype = nDealwithtype;
            HxTcpHandler.ReplyFailedMessage(hxMessage, hxMessage.OriginJSON, str_errCode, str_Message, nDealwithtype, p_Troubleshoot, nDealwithtype);
        }
 
        public bool MatchTSCode(int TS_Code)
        {
            return (p_Troubleshoot & TS_Code) > 0;
        }
 
        /// <summary>
        /// 阻塞等待用户反馈
        /// </summary>
        public void Wait()
        {
            b_onWaiting = true;
            while (r_Troubleshoot < 0)
            {
                Thread.Sleep(500);
            }
            b_onWaiting = false;
        }
 
        /// <summary>
        /// 异步等待用户反馈
        /// </summary>
        public async void WaitAsync()
        {
            b_onWaiting = true;
            await Task.Run(() =>
            {
                while (r_Troubleshoot < 0)
                {
                    Thread.Sleep(500);
                }
            });
            b_onWaiting = false;
        }
 
        /// <summary>
        /// 同步处理用户反馈
        /// </summary>
        /// <param name="TroubleshootReply"></param>
        public void Reply(int TroubleshootReply)
        {
            r_Troubleshoot = TroubleshootReply;
            if (TroubleshootReply == TS_Ignore)
                IgnoreTrigger.Invoke();
            else if (TroubleshootReply == TS_Retry)
                RetryTrigger.Invoke();
            else if (TroubleshootReply == TS_Abort)
                AbortTrigger.Invoke();
        }
 
        /// <summary>
        /// 异步处理用户反馈
        /// </summary>
        /// <param name="TroubleshootReply"></param>
        public async void ReplyAsync(int TroubleshootReply)
        {
            r_Troubleshoot = TroubleshootReply;
            if (TroubleshootReply == TS_Ignore)
                await Task.Run(() => { IgnoreTrigger.Invoke(); });
            else if (TroubleshootReply == TS_Retry)
                await Task.Run(() => { RetryTrigger.Invoke(); });
            else if (TroubleshootReply == TS_Abort)
                await Task.Run(() => { AbortTrigger.Invoke(); });
        }
 
        ~HxTroubleShoot()
        {
            Delegate[] dels;
            if (IgnoreTrigger != null)
            {
                dels = IgnoreTrigger.GetInvocationList();
                foreach (Delegate del in dels)
                {
                    object delObj = del.GetType().GetProperty("Method").GetValue(del, null);
                    string funcName = (string)delObj.GetType().GetProperty("Name").GetValue(delObj, null);
                    Console.WriteLine(funcName);
                    IgnoreTrigger -= del as TroubleShootDelegate;
                }
            }
 
            if (RetryTrigger != null)
            {
                dels = RetryTrigger.GetInvocationList();
                foreach (Delegate del in dels)
                {
                    object delObj = del.GetType().GetProperty("Method").GetValue(del, null);
                    string funcName = (string)delObj.GetType().GetProperty("Name").GetValue(delObj, null);
                    Console.WriteLine(funcName);
                    RetryTrigger -= del as TroubleShootDelegate;
                }
            }
 
            if (AbortTrigger != null)
            {
                dels = AbortTrigger.GetInvocationList();
                foreach (Delegate del in dels)
                {
                    object delObj = del.GetType().GetProperty("Method").GetValue(del, null);
                    string funcName = (string)delObj.GetType().GetProperty("Name").GetValue(delObj, null);
                    Console.WriteLine(funcName);
                    AbortTrigger -= del as TroubleShootDelegate;
                }
            }
        }
    }
 
    interface IInstruction
    {
    }
 
    public class HxInstruction: IInstruction
    {
        public const int INSTYPE_HeartBeat = 0;    // 类型:心跳包
        public const int INSTYPE_Task = 1;         // 类型:任务,指有较长执行时间的指令
        public const int INSTYPE_Query = 2;        // 类型:查询,指即时返回的指令
        public const int INSTYPE_Troubleshoot = 3; // 类型:错误处理,指客户端返回的问题处理指令
 
        public const int TASKSTAT_Scheduled = 0;    // 状态:准备执行
        public const int TASKSTAT_InProgress = 1;   // 状态:正在执行
        public const int TASKSTAT_Completed = 2;    // 状态:执行完成
        public const int TASKSTAT_Failed = 3;       // 状态:执行失败
        public const int TASKSTAT_Canceled = 4;     // 状态:任务取消
 
        protected HxMessage m_Message;     // 接收到的Socket信息包
        protected int n_TaskStatus;        // 任务状态
 
        public HxInstruction(HxMessage message)
        {
            m_Message = message;
            n_TaskStatus = -1;  // HxInstruction.TASKSTAT_Scheduled;
        }
 
        public string InsId { get { return m_Message.MessageID; } }   // 指令ID,唯一
        public string InsName { get { return m_Message.Method; } }   // 指令名
        public int Type { get { return m_Message.MessageType; } }       // 指令类型
        public int Status { get { return n_TaskStatus; } }                     // 指令执行状态
 
        public HxMessage Message { get { return m_Message; } }
    }
 
    /*
     * 心跳包指令
     */
    public class HeartBeatInstruction : HxInstruction
    {
        public HeartBeatInstruction(HxMessage message) : base(message) { }
    }
 
    /*
     * 任务指令
     */
    public class TaskInstruction : HxInstruction
    {
        HxInsParser command = null;
        public HxTroubleShoot ErrorHandler;
 
        public TaskInstruction(HxMessage message)
            : base(message)
        {
            ErrorHandler = new HxTroubleShoot();
        }
 
        public TaskInstruction(HxMessage message, HxInsParser cmd)
            : base(message)
        {
            ErrorHandler = new HxTroubleShoot();
            command = cmd;
        }
        
        public void OnTaskError(Object objMsg, string errCode, int TroubleshootPossibility, string message, int dealwithtype)
        {
            LogConstant.logger.Print($"OnTaskError: {message}");
            JObject jObj = objMsg as JObject;
            string id = jObj["message_id"].ToString();
            if (Message.MessageID == id)
                ErrorHandler.Error(this.Message, errCode, TroubleshootPossibility, message, dealwithtype);
            //ErrorHandler.WaitAsync();
        }
        public void OnTaskAbort(Object objMsg, string errCode, int TroubleshootPossibility, string message, int dealwithtype)
        {
            ErrorHandler.Abort(this.Message, errCode, TroubleshootPossibility, message, dealwithtype);
            //ErrorHandler.WaitAsync();
        }
 
        public void OnFinishTest(Dictionary<string,int> result)
        {
            JObject data = new JObject();// StartExperimentInsArgs.ReturnDataWrapper(result);
            HxTcpHandler.ReplyFinishMessage(this.Message, data);
        }
 
        // 指令已收到,执行状态转为Scheduled
        public void Standby()
        {
            n_TaskStatus = TASKSTAT_Scheduled;
        }
 
        // 指令下发设备,开始正式执行
        public void Execute()
        {
            n_TaskStatus = TASKSTAT_InProgress;
        }
 
        // 指令已经执行完毕,并正常结束
        public void Finish()
        {
            n_TaskStatus = TASKSTAT_Completed;
        }
 
        // 指令已经执行但被迫中断或执行失败
        public void Abort()
        {
            n_TaskStatus = TASKSTAT_Failed;
        }
    }
 
    /*
     * 查询指令
     */
    public class QueryInstruction : HxInstruction
    {
        HxInsParser command = null;
        public QueryDataDelegate OnDataReturned;
 
        public QueryInstruction(HxMessage message)
            : base(message){}
 
        public QueryInstruction(HxMessage message, HxInsParser cmd) 
            : base(message) 
        {
            command = cmd;
        }
    }
 
    /*
     * 错误处理指令
     */
    public class TroubleshootInstruction : HxInstruction
    {
        public TroubleshootInstruction(HxMessage message) : base(message) { }
 
        public int TSCode
        {
            get
            {
                return m_Message.Troubleshoot;
            }
        }
    }
 
    public class InstructionManager
    {
        TaskInstruction t_Instrction = null;    // 任务指令
        //ConcurrentQueue<QueryInstruction> q_Instructions;   // 查询指令队列
        readonly static object qryLock = new object();   // 查询指令队列锁
 
        System.Threading.Timer qTimer;
        private InsProtocol insProtocol;
 
        /// <summary>
        /// 监控查询指令队列
        /// </summary>
        /// <param name="state">占位参数</param>
        /*protected void QueueObserver(object state)
        {
            QueryInstruction qIns = null;
            bool deqFlag = false;
            lock (qryLock)
            {
                // 当查询队列中有指令未处理时取出
                if (q_Instructions.Count > 0)
                    deqFlag = q_Instructions.TryDequeue(out qIns);
                else
                    return;
            }
 
            try
            {
                if (deqFlag && qIns != null)
                {
                    // 执行查询指令
                    JObject data = insProtocol.Query(qIns);
                    if (data == null)
                        data = new JObject();
                    HxTcpHandler.ReplyFinishMessage(qIns.Message,data);
                }
            }
            catch (Exception ex)
            {
                HxTcpHandler.ReplyFailedMessage(qIns.Message, new JObject(), "ERROR", qIns.InsName+" error", 4);
            }
        }*/
 
        public InstructionManager()
        {
            //q_Instructions = new ConcurrentQueue<QueryInstruction>();
            insProtocol = new InsProtocol();
 
            // 启动定时器,每100ms查看一次查询队列中是否有新的查询任务
            //qTimer = new System.Threading.Timer(QueueObserver, null, 0, 100);
        }
 
        public void OnConnect(bool isConnect)
        {
            insProtocol.OnConnect(isConnect);
        }
        /// <summary>
        /// 当任务指令完成时调用该函数反馈给客户端
        /// </summary>
        /// <param name="data">任务产生的数据</param>
        /// <param name="status">任务完成时的状态</param>
        public void OnTaskFinish(TaskInstruction tIns, JObject data, int status)
        {
            if (tIns != null)
            {
                if (status == HxMessage.METHOD_STATUS_COMPLETED)
                {
                    tIns.Finish();
                    // 返回任务结束信息
                    HxTcpHandler.ReplyFinishMessage(
                            tIns.Message,
                            data);
                }
                else
                {
                    tIns.Abort();
 
                    HxTcpHandler.ReplyFailedMessage(tIns.Message,data,"EC-00-000", "OnTaskFinish status=failed");
                }
            }
        }
 
        /// <summary>
        /// 当任务指令完成时调用该函数反馈给客户端
        /// </summary>
        /// <param name="data">任务产生的数据</param>
        /// <param name="status">任务完成时的状态</param>
        public void OnTaskAbort(TaskInstruction tIns, string errCode, string errString)
        {
            if (tIns != null)
            {
                tIns.Abort();
 
                HxTcpHandler.ReplyFailedMessage(tIns.Message, ResponseMessagePackage.NullData, "EC-00-000", errString);
            }
        }
 
        /// <summary>
        /// 设置当前设备的查任务指令
        /// </summary>
        /// <param name="tIns">任务指令</param>
        /// <exception cref="TaskUncompletedException">上一个任务指令还未完成</exception>
        public void Add(TaskInstruction tIns)
        {
            // 当前没有任务指令的时候
            //if (t_Instrction == null)
            //{
            //    t_Instrction = tIns;
            //}
            // 当前有任务指令的时候,需要判断该任务是否已完成
            //else
            {
 
                string msg = string.Format("收到指令:{0},{1}", tIns.InsName, tIns.InsId);
                LogConstant.logger.Print(msg);
                //// 如果任务准备进行或正在进行中,则抛出任务冲突的错误
                //if (t_Instrction.Status == TaskInstruction.TASKSTAT_Scheduled || 
                //    t_Instrction.Status == TaskInstruction.TASKSTAT_InProgress)
                //    throw new TaskUncompletedException(
                //        string.Format("执行冲突:任务\"{0}:{1}\"正在运行中", t_Instrction.InsName, t_Instrction.InsId));
 
                //// 如果设备处于TASKSTAT_Completed, TASKSTAT_Failed或TASKSTAT_Cancel状态,则重新将其设为准备态
                //else
                {
                    //t_Instrction = tIns;
                    //t_Instrction.Standby();
                }
            }
            // 异步执行任务
            insProtocol.AsyncTask(ref tIns, OnTaskFinish, OnTaskAbort);
        }
 
        /// <summary>
        /// 设置当前设备的查询指令
        /// </summary>
        /// <param name="qIns">查询指令</param>
        public void Add(QueryInstruction qIns)
        {
            lock (qryLock)
            {
                //q_Instructions.Enqueue(qIns);
            }
        }
 
        /// <summary>
        /// 设置当前设备的错误处理指令
        /// </summary>
        /// <param name="tsIns">错误处理指令</param>
        /// <exception cref="TaskUncompletedException">上一个任务指令还未完成</exception>
        public void Add(TroubleshootInstruction tsIns)
        {
            // 只有在当前任务存在,且当前任务正在执行过程中,且当前任务与错误处理的ID相同的情况下
            if (t_Instrction == null)
            {
                LogConstant.logger.Print("没有前置错误可以处理");
                return;
            }
            if (t_Instrction.Status != TaskInstruction.TASKSTAT_InProgress)
            {
                LogConstant.logger.Print(string.Format("任务状态不符合错误处理要求,当前状态为:{0}", t_Instrction.Status));
                return;
            }
            if (!tsIns.InsId.Equals(t_Instrction.InsId))
            {
                LogConstant.logger.Print(string.Format("任务ID不一致,当前需要处理的任务ID为:{0}", t_Instrction.InsId));
                return;
            }
            if (!t_Instrction.ErrorHandler.MatchTSCode(tsIns.TSCode))
            {
                LogConstant.logger.Print(string.Format("错误处理方式{0}不符合要求", tsIns.TSCode));
                return;
            }
 
            LogConstant.logger.Print(string.Format("开始处理错误,TS Code={0}", tsIns.TSCode));
            t_Instrction.ErrorHandler.ReplyAsync(tsIns.TSCode);
        }
 
    }
}