• 解决仪器掉线备忘


    网络管控越来越严格,老的Mac模式连接的仪器经常断开,要么是网络没活动被断开TCP了,要么是网络波动无法保持TCP。每次重启仪器控制很麻烦,基于之前用M写http服务的基础上改进仪器接口连接。
    参照之前实现http服务的逻辑

    最终逻辑

    ///要实现客户端断线重连就拷贝此方法到仪器接口,仪器主处理函数约定为Main,Main异常记得给ShouldQClient变量设置1或者不捕获异常
    ///主侦听函数,有线程处理客户端请求,循环判断客户端连入
    ///启动主侦听
    ///d ListenMian^MI.MIF000(mi,"Start")
    ListenMian(mi,startFunName)  
         s IP=$li(^dbo.BTMIMachineParameterD(mi),9)
         s Port=$li(^dbo.BTMIMachineParameterD(mi),10)
         //数据库是服务端
         i '$l(IP) d
         .//检查停止标志
         .i $$Stop^MI.MIF000(mi) q
         .u Device
         .//用子线程处理客户端请求
         .//j DealClient:(:17::) 
         .d Trace^MI.MIF000(mi,"新客户端连入本TCP服务","LISSYS")
         .d DealClient(mi)
         .d Trace^MI.MIF000(mi,"因为报错退出一轮DealClient","LISSYS")
         .//检查停止标志
         .i $$Stop^MI.MIF000(mi) q
         .//GOTO做成循环 
         .d ListenMian(mi,startFunName)
         e  d
         .s IFProgram=$lg($g(^dbo.BTMIMachineParameterD(mi)),16)
         .s MainStr="d Main^"_IFProgram
         .s ShouldQClient=0
         .s ShouldStopMI=0
         .//循环执行Main方法,直到表标识要退出或者标识变量要退出
    	 .f  q:(ShouldQClient=1)||(ShouldStopMI=1)  d 
    	 ..//捕获错误,防止Main没捕获错误异常退出了
         ..SET $ZTRAP="ErrHandleClient",$ECODE=""  //捕获错误开始 
    	 ..x MainStr 
    	 ..s ShouldStopMI=$$Stop^MI.MIF000(mi)
         q
     
    ///当客户端发生错误捕获    
    ErrHandleClient 
        SET $ZTRAP=""
        h 1
        s ErrCode=$ECODE
        d Trace^MI.MIF000(mi,$TR($ZERROR,"^","--")_".错误代码:"_ErrCode,"当客户端运行")
        //串口不能读了就重连
    	i ErrCode["READ" d 
    	.d Trace^MI.MIF000(mi,"TCP重连中","尝试重连")
    	.d ReconnectServer
    	//其他的异常还是退出
    	e  s ShouldQClient=1
        q 1 
        
    ///客户端重连方法实现 
    ReconnectServer
        //检查停止标志
        i $$Stop^MI.MIF000(mi) q
        c Port
        c Device
    	h 1
    	l -^MILOCK(mi)
    	d Trace^MI.MIF000(mi,"移除锁","新起动TCP")
    	s StartStr="(startRet) s startRet=$$"_startFunName_"^MI.MIF000("_mi_")"
    	d Trace^MI.MIF000(mi,StartStr,"新起动TCP调用")
    	s startRet=""
    	x (StartStr,.startRet)
    	d Trace^MI.MIF000(mi,startRet,"新起动TCP返回")
    	//重连失败又尝试这里启动方法和上面一致
    	i startRet d ReconnectServer
    	d Trace^MI.MIF000(mi,"成功启动","新起动TCP")
    	q
     
         
         
    ///要实现客户端断线重连就拷贝此方法到仪器接口,仪器主处理函数约定为Main,Main异常记得给ShouldQClient变量设置1    
    ///处理客户端请求  
    DealClient(mi) 
        //s Device=##class(%SYSTEM.INetInfo).TCPName()
        //客户端输入的数据
        //s input=$PRINCIPAL
        //s output=$IO
        //s record=""
        //u Device:(::"M") 
        //标识是否结束客户端处理 
        s IFProgram=$lg($g(^dbo.BTMIMachineParameterD(mi)),16)
        s ShouldQClient=0
        s ShouldStopMI=0
        s MainStr="d Main^"_IFProgram
        d Trace^MI.MIF000(mi,"循环执行:"_MainStr,"LISSYS")
        //循环执行Main方法,直到表标识要退出或者标识变量要退出
    	f  q:(ShouldQClient=1)||(ShouldStopMI=1)  d  
    	.//捕获错误,防止Main没捕获错误异常退出了
        .SET $ZTRAP="ErrHandleServer",$ECODE=""  //捕获错误开始
    	.x MainStr 
    	.s ShouldStopMI=$$Stop^MI.MIF000(mi)
    	q
    	
    ///当服务端发生错误捕获    
    ErrHandleServer 
        SET $ZTRAP=""
        h 1
        s ShouldQClient=1
        d Trace^MI.MIF000(mi,$TR($ZERROR,"^","--")_".错误代码:"_$ECODE,"当服务端运行")
        q 1 
        
    
    • 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

    使用方式如下图
    在这里插入图片描述

    数据库当服务端原理
    原理就是对Cache做服务端的接口,启动一个主侦听来侦听客户端的连接,由于是给仪器连接的所以把http服务实现的用进程处理客户端连接就不用进程了,因为仪器只有一个在用连接。仪器接口没出错时候主侦听堵塞处理不了新客户端连接也无所谓,仪器处理异常后代码又退回到主侦听,就能处理新的客户端连入。

    数据库当客户端原理
    数据库当客户端时候连别人的TCP服务,如果异常了就会进入异常捕获,这时候调用重连逻辑就能重新起来TCP连接,重连不一定成功,这时候就进入一直重连的死循环,直到成功。重Start之前先关闭之前端口和设备。重连成功后就会跳出重连的死循环继续回到Main的执行上。

    此方案不用动连接模式,只要改一行接口代码就能支持断开重连,解决麻烦的仪器掉线问题

  • 相关阅读:
    如何解决Word文件打不开呢?几个简单的步骤
    纯 Java 撸个后台管理系统,这框架用起来贼好
    流量有了,却没有带来预期的业务增长?
    【JavaEE基础与高级 第56章】Java中的打印流、属性集、IO流异常的处理详细使用介绍
    Spring扩展接口(3):BeanFactoryPostProcessor
    java计算机毕业设计咖啡屋订单系统MyBatis+系统+LW文档+源码+调试部署
    【web APIs】4、(学习笔记)有案例!
    spring编程常见错误2 (学习笔记)
    《深度学习进阶:自然语言处理》读书笔记:第3章 word2vec
    AEM TESTPRO K50 ROADSHOW华南区路演
  • 原文地址:https://blog.csdn.net/zhanglianzhu_91/article/details/133318328