from .peers import Peer, ConnectionState from .events import Events, DynamicEvents from libs.fspn.utils.observable import Event from libs.fspn.protocol.connection import Connection, EVENTS as CONNECTION_EVENTS from libs.app.common.logging import get_logger logger = get_logger("connections") class ConnectionManager: """Handles peer connections""" # TODO Maybe peerManager receveid events and change status, reconnections, disconnections, etc. This class can just manage limits of connections, idk! def __init__(self, nosys_core): from .noSysCore import NoSysCore self.nosys_core:NoSysCore = nosys_core def connect(self, address, user_id, bind_address=("0.0.0.0", 0)): peer, connect = self.create_connection(address, user_id, bind_address) connect() return peer def create_connection(self, address, user_id, bind_address=("0.0.0.0", 0)): user = self.nosys_core.users.get_user(user_id) if not user: raise Exception("Cannot connect, user missing") connection = Connection(user.public_key, self.nosys_core.modules.pmc) connection.subscribe_event(CONNECTION_EVENTS.ON_CONNECTION, self._on_connection) connection.subscribe_event(CONNECTION_EVENTS.ON_CONNECTION_ERROR, self._on_connection_error) connection.subscribe_event(CONNECTION_EVENTS.ON_DISCONNECTION, self._on_disconnection) connection.subscribe_event(CONNECTION_EVENTS.ON_MESSAGE, self.nosys_core.dispatcher.on_message) peer = self.nosys_core.peers.create_peer(connection) self.nosys_core.peers.add_peer(peer) def connect(): connection.connect(address, bind_address) return peer, connect def disconnect(self, peer_id: str): self.nosys_core.peers.remove_peer(peer_id) def _on_connection(self, event:Event): connection:Connection = event.source logger.debug(f'New connection {connection.address} ID: {connection.id}') peer = self.nosys_core.peers.get_peer(connection.id) peer.state = ConnectionState.CONNECTED self.nosys_core.fire_event(Events.PEER_CONNECTED, peer=peer) self.nosys_core.fire_event(DynamicEvents.peer_connection(peer.id), peer=peer) logger.debug(f'Peer connected: {peer.get_my_user()} -> {peer.get_peer_user()}') def _on_connection_error(self, event:Event): connection:Connection = event.source error = event.error peer = self.nosys_core.peers.get_peer(connection.id) peer.state = ConnectionState.DISCONNECTED self.nosys_core.fire_event(Events.PEER_CONNECTION_ERROR, peer=peer, error=error) self.nosys_core.fire_event(DynamicEvents.peer_connection_error(peer.id), peer=peer, error=error) def _on_disconnection(self, event:Event): connection:Connection = event.source logger.debug('Disconnection', event.__dict__) peer = self.nosys_core.peers.get_peer(connection.id) peer.state = ConnectionState.DISCONNECTED self.nosys_core.fire_event(Events.PEER_DISCONNECTED, peer=peer) self.nosys_core.fire_event(DynamicEvents.peer_disconnection(peer.id), peer=peer)