解决仪器掉线备忘
- 人工智能
- 2025-08-18 15:48:01

网络管控越来越严格,老的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 .u Device READ x .u 0 .u Device .//用子线程处理客户端请求 .//j DealClient:(:17::) .d Trace^MI.MIF000(mi,"新客户端连入本TCP服务","LISSYS") .d DealClient(mi) .//检查停止标志 .i $$Stop^MI.MIF000(mi) q .//GOTO做成循环 .d ListenMian(mi) e d .s IFProgram=$lg($g(^dbo.BTMIMachineParameterD(mi)),16) .s MainStr="d Main^"_IFProgram .s ShouldQClient=0 .//循环执行Main方法,直到表标识要退出或者标识变量要退出 .f d ..//捕获错误,防止Main没捕获错误异常退出了 ..SET $ZTRAP="ErrHandleClient",$ECODE="" //捕获错误开始 ..x MainStr i $$Stop^MI.MIF000(mi)||(ShouldQClient=1) q 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 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 MainStr="d Main^"_IFProgram d Trace^MI.MIF000(mi,"循环执行:"_MainStr,"LISSYS") //循环执行Main方法,直到表标识要退出或者标识变量要退出 f d .//捕获错误,防止Main没捕获错误异常退出了 .SET $ZTRAP="ErrHandleServer",$ECODE="" //捕获错误开始 .x MainStr i $$Stop^MI.MIF000(mi)||(ShouldQClient=1) q q ///当服务端发生错误捕获 ErrHandleServer SET $ZTRAP="" h 1 d Trace^MI.MIF000(mi,$TR($ZERROR,"^","--")_".错误代码:"_$ECODE,"当服务端运行") q 1使用方式如下图
数据库当服务端原理 原理就是对Cache做服务端的接口,启动一个主侦听来侦听客户端的连接,由于是给仪器连接的所以把http服务实现的用进程处理客户端连接就不用进程了,因为仪器只有一个在用连接。仪器接口没出错时候主侦听堵塞处理不了新客户端连接也无所谓,仪器处理异常后代码又退回到主侦听,就能处理新的客户端连入。
数据库当客户端原理 数据库当客户端时候连别人的TCP服务,如果异常了就会进入异常捕获,这时候调用重连逻辑就能重新起来TCP连接,重连不一定成功,这时候就进入一直重连的死循环,直到成功。重Start之前先关闭之前端口和设备。重连成功后就会跳出重连的死循环继续回到Main的执行上。
此方案不用动连接模式,只要改一行接口代码就能支持断开重连,解决麻烦的仪器掉线问题
上一篇
Docker网络+资源控制