Esempio n. 1
0
    def disconnect(self):
        """
        Disconnect
        """

        if self._soc:
            SolBase.safe_close_socket(self._soc)
            self._soc = None
Esempio n. 2
0
    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)
Esempio n. 3
0
    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)
Esempio n. 4
0
    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