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,48 @@ 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 ) -> bool :
60+ #print("validateConnection")
61+ diff_ms = - 1
62+ need_reconnect = False
63+ if self .last_keep_alive_ms > 0 :
64+ now = time .ticks_ms ()
65+ diff_ms = now - self .last_keep_alive_ms
66+ if diff_ms > _RECONNECT_NO_KEEP_ALIVE_MS :
67+ need_reconnect = True
68+ if True :
69+ if need_reconnect :
70+ if self .reconnect_enabled :
71+ print ("disconnected ... reconnecting ... " , self .reconnect_RC_id , diff_ms )
72+ else :
73+ print ("disconnected" )
74+ if need_reconnect :
75+ self .reconnecting = True
76+ if need_reconnect and self .reconnect_enabled :
77+ try :
78+ self ._io .print ("%%>RECON>" )
79+ self ._io .print (_DD_SID )
80+ self ._io .print (":" )
81+ self ._io .print (self .reconnect_RC_id )
82+ self ._io .print ("\n " )
83+ except :
84+ pass
85+ self .reconnect_keep_alive_ms = self .last_keep_alive_ms
86+ elif self .reconnect_keep_alive_ms > 0 :
87+ self .reconnecting = False
88+ #_ConnectVersion = _ConnectVersion + 1;
89+ self .reconnect_keep_alive_ms = 0
90+ self .last_keep_alive_ms = time .ticks_ms ()
91+ return not need_reconnect
92+ def isReconnecting (self ) -> bool :
93+ return self .reconnecting ;
4394
4495_NextLayerNid : int = 0
4596def _AllocLayerNid ():
@@ -57,14 +108,21 @@ def __init__(self, io: DDInputOutput):
57108 self ._connected_iop : IOProxy = None
58109 self ._layers : dict [DDLayer ] = {}
59110 self ._tunnels : dict = {}
60-
111+ self .last_validate_ms = 0
112+
61113 def timeslice (self ):
62114 self ._checkForFeedback ()
63115
64116 def delay (self , seconds : float = 0 ):
65- self .delay_ms (seconds * 1000 )
117+ '''
118+ use sleep() instead
119+ '''
120+ self .sleep_ms (seconds * 1000 )
121+
122+ def sleep (self , seconds : float = 0 ):
123+ self .sleep_ms (seconds * 1000 )
66124
67- def delay_ms (self , ms : int = 0 ):
125+ def sleep_ms (self , ms : int = 0 ):
68126 self ._checkForFeedback ()
69127 until_ms = int (time .ticks_ms () + ms )
70128 while True :
@@ -90,11 +148,13 @@ def release(self):
90148 self ._connected = False
91149 self ._connected_iop = None
92150
93- def toggleDebugLed (self ):
151+ # def toggleDebugLed(self):
152+ # pass
153+ # def switchDebugLed(self, on):
154+ # pass
155+ def onDetectedDisconnect (self ):
94156 pass
95- def switchDebugLed (self , on ):
96- pass
97- def onSendCommandException (self , os_error ):
157+ def onSendCommandException (self , error ):
98158 pass
99159
100160 def _allocLayerNid (self ):
@@ -109,9 +169,8 @@ def _createLayer(self, layer_type: str, *params) -> str:
109169 layer_id = str (self ._allocLayerNid ())
110170 self ._sendCommand (layer_id , "SU" , layer_type , * params )
111171 return layer_id
112- def _reorderLayer (self , layer_id : str , how : str ): {
172+ def _reorderLayer (self , layer_id : str , how : str ):
113173 self ._sendCommand (layer_id , "REORD" , how )
114- }
115174 def _deleteLayer (self , layer_id : str ):
116175 self ._sendCommand (layer_id , "DEL" )
117176 def _onCreatedLayer (self , layer : DDLayer ):
@@ -129,7 +188,7 @@ def _connect(self):
129188 if self ._connected :
130189 return
131190
132- self .switchDebugLed (True )
191+ # self.switchDebugLed(True)
133192 self ._io .preconnect ()
134193
135194 # > ddhello and < ddhello
@@ -139,7 +198,7 @@ def _connect(self):
139198 now = time .ticks_ms ()
140199 if now > next_time :
141200 iop .print ('ddhello\n ' )
142- self .toggleDebugLed ()
201+ # self.toggleDebugLed()
143202 next_time = now + _HS_GAP
144203 if iop .available ():
145204 data = iop .read ()
@@ -156,7 +215,7 @@ def _connect(self):
156215 now = time .ticks_ms ()
157216 if now > next_time :
158217 iop .print ('>init>:' + _DD_SID + '\n ' )
159- self .toggleDebugLed ()
218+ # self.toggleDebugLed()
160219 next_time = now + _HS_GAP
161220 if iop .available ():
162221 data = iop .read ()
@@ -170,12 +229,12 @@ def _connect(self):
170229
171230 self ._connected = True
172231 self ._compatibility = compatibility
173- self .switchDebugLed (False )
232+ # self.switchDebugLed(False)
174233 #print('connected:' + str(compatibility))
175234
176235 def _sendSpecial (self , special_type : str , special_id : str , special_command : str , special_data : str ):
177236 ##print("lt:" + str(special_command) + ":" + str(special_data))#####
178- self .switchDebugLed (True )
237+ # self.switchDebugLed(True)
179238 self ._io .print ('%%>' )
180239 self ._io .print (special_type )
181240 self ._io .print ('.' )
@@ -187,10 +246,10 @@ def _sendSpecial(self, special_type: str, special_id: str, special_command: str,
187246 if special_data != None :
188247 self ._io .print (special_data )
189248 self ._io .print ('\n ' )
190- self .switchDebugLed (False )
249+ # self.switchDebugLed(False)
191250 def _sendCommand (self , layer_id : str , command : str , * params ):
192251 self ._checkForFeedback ()
193- self .switchDebugLed (True )
252+ # self.switchDebugLed(True)
194253 try :
195254 if layer_id != None :
196255 self ._io .print (layer_id )
@@ -202,11 +261,12 @@ def _sendCommand(self, layer_id: str, command: str, *params):
202261 else :
203262 self ._io .print (',' )
204263 self ._io .print (params [i ])
205- except OSError as e :
206- self .switchDebugLed (False )
264+ self ._io .print ('\n ' )
265+ except Exception as e :
266+ #self.switchDebugLed(False)
207267 self .onSendCommandException (e )
208- self ._io .print ('\n ' )
209- self .switchDebugLed (False )
268+ # self._io.print('\n')
269+ # self.switchDebugLed(False)
210270
211271
212272
@@ -215,8 +275,10 @@ def _checkForFeedback(self):
215275 if feedback != None :
216276 if len (feedback ) > 0 :
217277 if feedback [0 :1 ] == '<' :
278+ self ._onFeedbackKeepAlive ()
218279 if len (feedback ) == 1 :
219- self ._onFeedbackKeepAlive ()
280+ pass
281+ #self._onFeedbackKeepAlive()
220282 else :
221283 #print(feedback)####
222284 if feedback .startswith ('<lt.' ):
@@ -265,19 +327,30 @@ def _checkForFeedback(self):
265327 except :
266328 pass
267329 def _readFeedback (self ) -> str :
330+ if not self ._validateConnection ():
331+ self .onDetectedDisconnect ()
268332 if not self ._connected_iop .available ():
269333 return None
270334 feedback = self ._connected_iop .read ()
271335 #self._connected_iop.clear()
272336 return feedback
273337 def _onFeedbackKeepAlive (self ):
274- pass
275- # def _onFeedback(self, lid, type, x, y):
276- # layer = self.layers.get(lid)
277- # if layer != None:
278- # layer._handleFeedback(type, x, y)
279- # #print("FB: " + layer.layer_id + '.' + type + ':' + str(x) + ',' + str(y))
280-
338+ if self ._connected_iop :
339+ self ._connected_iop .keepAlive ()
340+ def _validateConnection (self ):
341+ if self ._connected_iop :
342+ validate_gap = _RECONNECTING_VALIDATE_GAP if self ._connected_iop .isReconnecting () else _VALIDATE_GAP
343+ now = time .ticks_ms ()
344+ diff_ms = now - self .last_validate_ms
345+ if diff_ms >= validate_gap :
346+ res = self ._connected_iop .validateConnection ()
347+ self .last_validate_ms = now
348+ else :
349+ res = True
350+ return res
351+ def _setReconnectRCId (self , rc_id : str ):
352+ if self ._connected_iop :
353+ self ._connected_iop .setReconnectRCId (rc_id )
281354 def _createTunnel (self , end_point ):
282355 tunnel_id = str (self ._allocTunnelNid ())
283356 self ._sendSpecial ("lt" , tunnel_id , "connect" , end_point )
0 commit comments