1515
1616_HS_GAP : int = 1000
1717
18+ _RECONNECT_NO_KEEP_ALIVE_MS : int = 5000
19+ _VALIDATE_GAP : int = 1000
20+ _RECONNECTING_VALIDATE_GAP : int = 500
21+
1822
1923class IOProxy :
2024 def __init__ (self , io ):
2125 self ._io = io
2226 self .data : str = ''
27+ self .last_keep_alive_ms = 0
28+ self .reconnect_keep_alive_ms = 0
29+ self .reconnecting = False
30+ self .reconnect_enabled = False
31+ self .reconnect_RC_id = None
2332 def available (self ):
2433 done = '\n ' in self .data
2534 while (not done ) and self ._io .available ():
@@ -40,6 +49,46 @@ def read(self) -> str:
4049 # self.data = ''
4150 def print (self , s ):
4251 self ._io .print (s )
52+ def keepAlive (self ):
53+ self .last_keep_alive_ms = time .ticks_ms ()
54+ def setReconnectRCId (self , rc_id : str ):
55+ ### reconnect not working yet
56+ self .reconnect_RC_id = rc_id
57+ self .reconnect_enabled = True
58+ self .reconnect_keep_alive_ms = 0
59+ def validateConnection (self ):
60+ #print("validateConnection")
61+ need_reconnect = False
62+ if self .last_keep_alive_ms > 0 :
63+ now = time .ticks_ms ()
64+ diff_ms = now - self .last_keep_alive_ms
65+ if diff_ms > _RECONNECT_NO_KEEP_ALIVE_MS :
66+ need_reconnect = True
67+ if True :
68+ if need_reconnect :
69+ if self .reconnect_enabled :
70+ print ("disconnected ... reconnecting ... " , self .reconnect_RC_id )
71+ else :
72+ print ("disconnected" )
73+ if need_reconnect :
74+ self .reconnecting = True
75+ if need_reconnect and self .reconnect_enabled :
76+ try :
77+ self ._io .print ("%%>RECON>" )
78+ self ._io .print (_DD_SID )
79+ self ._io .print (":" )
80+ self ._io .print (self .reconnect_RC_id )
81+ self ._io .print ("\n " )
82+ except :
83+ pass
84+ self .reconnect_keep_alive_ms = self .last_keep_alive_ms
85+ elif self .reconnect_keep_alive_ms > 0 :
86+ self .reconnecting = False
87+ #_ConnectVersion = _ConnectVersion + 1;
88+ self .reconnect_keep_alive_ms = 0
89+ self .last_keep_alive_ms = time .ticks_ms ()
90+ def isReconnecting (self ) -> bool :
91+ return self .reconnecting ;
4392
4493_NextLayerNid : int = 0
4594def _AllocLayerNid ():
@@ -57,7 +106,8 @@ def __init__(self, io: DDInputOutput):
57106 self ._connected_iop : IOProxy = None
58107 self ._layers : dict [DDLayer ] = {}
59108 self ._tunnels : dict = {}
60-
109+ self .last_validate_ms = 0
110+
61111 def timeslice (self ):
62112 self ._checkForFeedback ()
63113
@@ -100,7 +150,7 @@ def toggleDebugLed(self):
100150 pass
101151 def switchDebugLed (self , on ):
102152 pass
103- def onSendCommandException (self , os_error ):
153+ def onSendCommandException (self , error ):
104154 pass
105155
106156 def _allocLayerNid (self ):
@@ -115,9 +165,8 @@ def _createLayer(self, layer_type: str, *params) -> str:
115165 layer_id = str (self ._allocLayerNid ())
116166 self ._sendCommand (layer_id , "SU" , layer_type , * params )
117167 return layer_id
118- def _reorderLayer (self , layer_id : str , how : str ): {
168+ def _reorderLayer (self , layer_id : str , how : str ):
119169 self ._sendCommand (layer_id , "REORD" , how )
120- }
121170 def _deleteLayer (self , layer_id : str ):
122171 self ._sendCommand (layer_id , "DEL" )
123172 def _onCreatedLayer (self , layer : DDLayer ):
@@ -208,11 +257,12 @@ def _sendCommand(self, layer_id: str, command: str, *params):
208257 else :
209258 self ._io .print (',' )
210259 self ._io .print (params [i ])
211- except OSError as e :
212- self .switchDebugLed (False )
260+ self ._io .print ('\n ' )
261+ except Exception as e :
262+ #self.switchDebugLed(False)
213263 self .onSendCommandException (e )
214- self ._io .print ('\n ' )
215- self .switchDebugLed (False )
264+ # self._io.print('\n')
265+ # self.switchDebugLed(False)
216266
217267
218268
@@ -221,8 +271,10 @@ def _checkForFeedback(self):
221271 if feedback != None :
222272 if len (feedback ) > 0 :
223273 if feedback [0 :1 ] == '<' :
274+ self ._onFeedbackKeepAlive ()
224275 if len (feedback ) == 1 :
225- self ._onFeedbackKeepAlive ()
276+ pass
277+ #self._onFeedbackKeepAlive()
226278 else :
227279 #print(feedback)####
228280 if feedback .startswith ('<lt.' ):
@@ -271,19 +323,26 @@ def _checkForFeedback(self):
271323 except :
272324 pass
273325 def _readFeedback (self ) -> str :
326+ self ._validateConnection ()
274327 if not self ._connected_iop .available ():
275328 return None
276329 feedback = self ._connected_iop .read ()
277330 #self._connected_iop.clear()
278331 return feedback
279332 def _onFeedbackKeepAlive (self ):
280- pass
281- # def _onFeedback(self, lid, type, x, y):
282- # layer = self.layers.get(lid)
283- # if layer != None:
284- # layer._handleFeedback(type, x, y)
285- # #print("FB: " + layer.layer_id + '.' + type + ':' + str(x) + ',' + str(y))
286-
333+ if self ._connected_iop :
334+ self ._connected_iop .keepAlive ()
335+ def _validateConnection (self ):
336+ if self ._connected_iop :
337+ validate_gap = _RECONNECTING_VALIDATE_GAP if self ._connected_iop .isReconnecting () else _VALIDATE_GAP
338+ now = time .ticks_ms ()
339+ diff_ms = now - self .last_validate_ms
340+ if diff_ms >= validate_gap :
341+ self ._connected_iop .validateConnection ()
342+ self .last_validate_ms = now
343+ def _setReconnectRCId (self , rc_id : str ):
344+ if self ._connected_iop :
345+ self ._connected_iop .setReconnectRCId (rc_id )
287346 def _createTunnel (self , end_point ):
288347 tunnel_id = str (self ._allocTunnelNid ())
289348 self ._sendSpecial ("lt" , tunnel_id , "connect" , end_point )
0 commit comments