def main(): sio.connect('https://ishoal.ink/') ishoalc.wait_for_switch() if ishoalc.should_stop(): sio.disconnect() return def on_switch_change(): pulse() threading.Thread(target=ishoalc.on_switch_chg_threadfn, args=(on_switch_change,), name='py_switch_chg').start() def periodic_pulse_threadfn(): while not ishoalc.should_stop(): ishoalc.sleep(10 * 1000) pulse() threading.Thread(target=periodic_pulse_threadfn, name='py_pulse').start() # Python is dumb that signal handlers must execute on main thread :( # if we ishoalc.sleep(-1) then signal handler will never execute # wake up every 100ms to check for signals while not ishoalc.should_stop(): ishoalc.sleep(100) sio.disconnect()
def main(): global loop loop = handshake.start_handshaker() new_socketio() def on_switch_change(): if g_sio: g_sio.disconnect() threading.Thread(target=ishoalc.on_switch_chg_threadfn, args=(on_switch_change, ), name='py_switch_chg').start() # Python is dumb that signal handlers must execute on main thread :( # if we ishoalc.sleep(-1) then signal handler will never execute # wake up every 100ms to check for signals while not ishoalc.should_stop(): ishoalc.sleep(100) global finalizing finalizing = True if g_sio: g_sio.disconnect() loop.call_soon_threadsafe(loop.stop)
def periodic_pulse_threadfn(): while not ishoalc.should_stop(): ishoalc.sleep(10 * 1000) pulse()
def new_socketio(): ishoalc.wait_for_switch() if ishoalc.should_stop(): return all_connections = set() sio = socketio.Client(reconnection=False) sio.eio.logger.setLevel(logging.CRITICAL) def handshake_cb(typ, args): if typ == 'port_exchange': sio.emit('handshake', args) if typ == 'complete': switchip, *_ = args all_connections.add(switchip) ishoalc.add_connection(*args) if typ == 'timeout': switchip, = args print(f'* Remote IP {switchip}, handshake time out', file=remotes_log) if typ == 'error': switchip, e = args print( f'* Remote IP {switchip}, handshake error: ' f'{type(e).__qualname__}: {e}', file=remotes_log) try: with open('/var/log/ishoal-error.log', 'a') as f: traceback.print_exc(file=f) except Exception: pass @sio.on('disconnect') def on_disconnect(): for switchip in all_connections: ishoalc.delete_connection(switchip) global g_sio g_sio = None all_connections.clear() print('Disconnected', file=remotes_log) ishoalc.sleep(100) if not finalizing: new_socketio() @sio.on('connected') def on_connected(): sio.emit('protocol', (2, ishoalc.get_switch_ip())) global g_sio g_sio = sio print('Joined iShoal network', file=remotes_log) @sio.on('ip_collision') def on_ip_collision(): print( f'Cannot join iShoal network, ' f'{ishoalc.get_switch_ip()} collision', file=remotes_log) @sio.on('add_remote') def on_add_remote(remoteid, remoteip, switchip): if not isinstance(remoteip, str) or not IPV4_REGEXP.match(remoteip): return if not isinstance(switchip, str) or not IPV4_REGEXP.match(switchip): return handshake.do_handshake(loop, remoteid, remoteip, switchip, handshake_cb) @sio.on('handshake') def on_handshake(remoteid, exchangeid, port): if not isinstance(port, int) or not (0 < port < 65536): return if exchangeid not in (0, 1): return handshake.on_handshake_msg(loop, remoteid, exchangeid, port) @sio.on('del_remote') def on_del_remote(remoteid, remoteip, switchip): if not isinstance(switchip, str) or not IPV4_REGEXP.match(switchip): return all_connections.discard(switchip) ishoalc.delete_connection(switchip) try: sio.connect('https://ishoal.ink/') except Exception as e: print( f'Failed to join iShoal network, check connection? Error:\n' f'{type(e).__qualname__}: {e}', file=remotes_log) try: with open('/var/log/ishoal-error.log', 'a') as f: traceback.print_exc(file=f) except Exception: pass