def _on_connect(self, future): try: self._stream = future.result() except: log.exception( 'tcp_asnyc_client_connect_fail|id=%s,address=%s,port=%s', self._id, self._address, self._port) self._close() self._async_connect() return log.debug('tcp_asnyc_client_connect|id=%s,address=%s,port=%s', self._id, self._address, self._port) self._stream.set_close_callback(self._on_close) self._set_keep_alive() if self._on_connect_callback is not None: try: self._on_connect_callback(self) except: log.exception( 'tcp_asnyc_client_on_connect_exception|id=%s,address=%s,port=%s', self._id, self._address, self._port) if self._pending_buffer: self._stream.write(b''.join(self._pending_buffer)) self._pending_buffer = [] self._recv_header()
def _on_client_close(self, client): # log.debug('tcp_server_client_close|id=%s,remote=%s', client.id.encode('hex'), client.remote_address) log.debug('tcp_server_client_close|id=%s,remote=%s', byteshex(client.id), client.remote_address) if client.id not in self._clients: # log.error('tcp_server_close_conn_not_found|id=%s,remote=%s', client.id.encode('hex'), client.remote_address) log.error('tcp_server_close_conn_not_found|id=%s,remote=%s', byteshex(client.id), client.remote_address) return self._handle_task(client, GTCP_CMD_DISCONNECT, b'') del self._clients[client.id]
def _on_close(self): log.debug('tcp_asnyc_client_disconnect|id=%s,address=%s,port=%s', self._id, self._address, self._port) if self._on_disconnect_callback is not None: try: self._on_disconnect_callback(self) except: log.exception( 'tcp_asnyc_client_on_disconnect_exception|id=%s,address=%s,port=%s', self._id, self._address, self._port) self._async_connect()
def _on_worker_connect(self, stream, address): worker = GTcpConnection(stream, address, self._config, self._on_worker_packet, self._on_worker_close, endian="<") worker.running_task = None # log.debug('tcp_server_worker_connect|id=%s,remote=%s', worker.id.encode('hex'), worker.remote_address) log.debug('tcp_server_worker_connect|id=%s,remote=%s', worker.id, worker.remote_address) self._on_worker_idle(worker)
def _connect(self): try: self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) if self._timeout > 0: self._socket.settimeout(self._timeout) self._set_keep_alive() self._socket.connect((self._address, self._port)) log.debug('tcp_connect|address=%s,port=%u', self._address, self._port) return True except Exception as ex: log.exception('tcp_connect_fail|address=%s,port=%u,ex=%s', self._address, self._port, ex) self.close() return False
def _on_client_connect(self, stream, address): client = GTcpConnection(stream, address, self._config, self._on_client_packet, self._on_client_close, endian="!") if client.id in self._clients: # log.error('tcp_server_dup_client|id=%s,remote=%s', client.id.encode('hex'), client.remote_address) log.error('tcp_server_dup_client|id=%s,remote=%s', client.id, client.remote_address) self._clients[client.id] = client self._handle_task(client, GTCP_CMD_CONNECT, b'') # log.debug('tcp_server_client_connect|id=%s,remote=%s', client.id.encode('hex'), client.remote_address) log.debug('tcp_server_client_connect|id=%s,remote=%s', client.id, client.remote_address)
def run(self): random.seed() self.on_init() from sakura.gtcpclient import GTcpClient log.debug('tcp_worker_start|id=%d', self._id) self._client = GTcpClient(self._config.WORK_ENDPOINT['address'], self._config.WORK_ENDPOINT['port'], 0) while True: try: request = self._client.receive() if request is None: log.warn( 'tcp worker lost_connection|client_id=%s,client=%s', byteshex(self._id), self._client._address) self._client.close() elif len(request) < GTCP_HEADER_SIZE: log.error( 'tcp_worker_request_packet_error|client_id=%s,client=%s,request=%s', byteshex(self._id), self._client._address, byteshex(request)) self._client.close() else: request_cmd = request[:GTCP_CMD_SIZE] request_client = TcpEndpoint( request[GTCP_CMD_SIZE:GTCP_HEADER_SIZE]) reply_body = None if request_cmd == GTCP_CMD_RELAY: request_body = request[GTCP_HEADER_SIZE:] reply_body = self.on_packet(request_client, request_body) elif request_cmd == GTCP_CMD_CONNECT: reply_body = self.on_client_connect(request_client) elif request_cmd == GTCP_CMD_DISCONNECT: self.on_client_disconnect(request_client) if reply_body is None: self._client.send(GTCP_CMD_NONE + request_client.client_id) else: self._client.send(GTCP_CMD_RELAY + request_client.client_id + reply_body) except Exception as ex: log.exception('tcp_worker_exception|id=%u,exception=%s', self._id, ex, exc_info=True) self._client.close()
def _async_connect(self): log.debug('tcp_asnyc_client_try_connect|id=%s,address=%s,port=%s', self._id, self._address, self._port) TCPClient().connect(self._address, self._port).add_done_callback(self._on_connect)