def disconnect(self): """ Disconnect """ if self._soc: SolBase.safe_close_socket(self._soc) self._soc = None
def _disconnect_helper(self, reason): """ Fire a disconnect on our end and notify upper level is possible :param reason: Reason :type reason: str """ logger.debug("Disconnect from inside, reason=%s", reason) # Disengage r/w loops now # CAUTION : NEVER (NEVER) internally flag "is_connected=False" here, you will BLAST upper level implementations self.__internal_fatal_error = True # Close the socket SolBase.safe_close_socket(self.current_socket) self.current_socket = None # Callback now if self._callback_disconnect: self._callback_disconnect() else: logger.error("_disconnect_helper is None, check your implementation, self=%s", self)
def stop_synch_internal(self): """ Stop processing our socket read/write. Reserved for PURE in-memory stop operations (greenlet stop, counter put mainly) NEVER, NEVER perform any kind of non-memory operations here. For instance, are FORDIDEN in higher level implementation of stop_synch_internal : - Any socket send/recv - Any external queries (redis/mongo, whatever) JUST HANDLE IN MEMORY STUFF. :return True if success, false otherwise. :rtype bool """ try: logger.debug( "TcpServerClientContext : disconnect : entering, self=%s", self) # Check if not self.is_connected: logger.debug( "TcpServerClientContext : disconnect : not connected, doing nothing, self=%s", self) return False # Signal (move on top, try to avoid some TcpManager warn logs while stopping) self.is_connected = False # Timeout unschedule self._unschedule_ssl_handshake_timeout() # Control unschedule self._unschedule_control_greenlet() # Disconnect # Close the socket in this case (should not cover mantis 1173) SolBase.safe_close_socket(self.current_socket) self.current_socket = None # Greenlet reset after is_connected=False (will help to exit itself) if self._read_greenlet: self._read_greenlet.kill() self._read_greenlet = None if self._write_greenlet: self._write_greenlet.kill() self._write_greenlet = None # Flush out the send queue now, and decrement pending bytes to send total_len = 0 while True: try: item = self.send_queue.get(False) if isinstance(item, bytes): total_len += len(item) elif isinstance(item, SignaledBuffer): total_len += len(item.binary_buffer) except Empty: break # Decrement logger.debug( "TcpServerClientContext : disconnect : decrementing, total_len=%s", total_len) Meters.aii("tcp.server.server_bytes_send_pending", -total_len) # Over logger.debug("TcpServerClientContext : disconnect : done, self=%s", self) return True except Exception as e: logger.error( "TcpServerClientContext : disconnect : Exception, ex=%s, self=%s", SolBase.extostr(e), self) return False finally: # Session duration stats sec = SolBase.datediff(self._dt_created) / 1000 Meters.dtci("tcp.server.session_duration_second", sec)
def _register_client(self, socket, address): """ Register a new client. :param socket: The client socket. :type socket: socket.socket :param address: The client remote address :type address: str :return Return a TcpServerClientContext upon success, None upon failure. :rtype pysoltcp.tcpserver.clientcontext.TcpServerClientContext.TcpServerClientContext """ try: logger.debug("entering") # Must be started if self._is_started is False: logger.debug("not started, cannot process") return None # Allocate a new client context logger.debug("allocating new_client using factory") new_client = self._tcp_server_config.client_factory.get_new_clientcontext( self, self._client_connected_atomicint.increment(), socket, address) # Hash id logger.debug("hashing new_client") with self._client_connected_hash_lock: logger.debug("hashing new_client (in lock)") self._client_connected_hash[ new_client.get_client_id()] = new_client # Statistics logger.debug("populating statistics") Meters.aii("tcp.server.client_connected") Meters.aii("tcp.server.client_register_count") # Enable SSL if required and set handshake timeout if self._tcp_server_config.ssl_enable is True: new_client.set_ssl_handshake_asynch( True, self._tcp_server_config.ssl_handshake_timeout_ms, self._tcp_server_config.debug_waitinsslms) # Start the client logger.debug("starting client") new_client.start() # Log logger.debug("client started and hashed, id=%s, addr=%s", new_client.get_client_id(), new_client.get_client_addr()) return new_client except Exception as e: # Error logger.warning("extostr, ex=%s", SolBase.extostr(e)) # Statistics Meters.aii("tcp.server.clientRegisterException") # Close the socket in this case SolBase.safe_close_socket(socket) return None