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_recv_body(self, data): if self._on_receive_packet_callback is not None: try: self._on_receive_packet_callback(self, data) except: # log.exception('tcp_asnyc_client_on_receive_exception|id=%s,packet=%s', self._id, data.encode('hex')) log.exception( 'tcp_asnyc_client_on_receive_exception|id=%s,packet=%s', self._id, byteshex(data)) self._recv_header()
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 _func(*args, **kwargs): try: return func(*args, **kwargs) except: if keyword is None: log.exception('%s_exception', func.__name__) else: log.exception('%s_exception', keyword) if return_filter: return return_filter(exception_return) else: return exception_return
def request(self, request): if self._socket is None: if not self._connect(): return None packet = struct.pack('<I%ds' % len(request), len(request), request) try: self._socket.sendall(packet) length_data = self._recv(4) except Exception as ex: self.close() if not self._retry: # log.exception('tcp_request_fail|error=recv_length_fail,address=%s,port=%u,request=%s', self._address, self._port, request.encode('hex')) log.exception( 'tcp_request_fail|error=recv_length_fail,address=%s,port=%u,request=%s', self._address, self._port, byteshex(request)) return None if isinstance(ex, socket.timeout): # log.exception('tcp_request_fail|error=recv_length_timeout,address=%s,port=%u,retry=0,request=%s', self._address, self._port, request.encode('hex')) log.exception( 'tcp_request_fail|error=recv_length_timeout,address=%s,port=%u,retry=0,request=%s', self._address, self._port, byteshex(request)) return None # log.warn('tcp_request_fail|error=recv_length_fail_will_retry,address=%s,port=%u,retry=0,request=%s,ex=%s', self._address, self._port, request.encode('hex'), ex) log.warn( 'tcp_request_fail|error=recv_length_fail_will_retry,address=%s,port=%u,retry=0,request=%s,ex=%s', self._address, self._port, byteshex(request), ex) if not self._connect(): # log.exception('tcp_request_fail|error=retry_reconnect,address=%s,port=%u,retry=0,request=%s', self._address, self._port, request.encode('hex')) log.exception( 'tcp_request_fail|error=retry_reconnect,address=%s,port=%u,retry=0,request=%s', self._address, self._port, byteshex(request)) return None try: self._socket.sendall(packet) length_data = self._recv(4) except Exception as ex: # log.exception('tcp_request_fail|error=retry_recv_length_fail,address=%s,port=%u,retry=1,request=%s', self._address, self._port, request.encode('hex')) log.exception( 'tcp_request_fail|error=retry_recv_length_fail,address=%s,port=%u,retry=1,request=%s', self._address, self._port, byteshex(request)) self.close() return None try: length = struct.unpack('<I', length_data)[0] return self._recv(length) except Exception as ex: # log.exception('tcp_request_fail|error=recv_data_fail,address=%s,port=%u,request=%s', self._address, self._port, request.encode('hex')) log.exception( 'tcp_request_fail|error=recv_data_fail,address=%s,port=%u,request=%s', self._address, self._port, byteshex(request)) self.close() return None
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 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 send(self, request): if self._socket is None: if not self._connect(): return False packet = struct.pack('<I%ds' % len(request), len(request), request) try: self._socket.sendall(packet) return True except Exception as ex: self.close() if not self._retry: # log.exception('tcp_send_fail|error=send_fail,address=%s,port=%u,request=%s', self._address, self._port, request.encode('hex')) log.exception( 'tcp_send_fail|error=send_fail,address=%s,port=%u,request=%s', self._address, self._port, byteshex(request)) return False # log.warn('tcp_send_fail|error=send_fail_will_retry,address=%s,port=%u,retry=0,request=%s,ex=%s', self._address, self._port, request.encode('hex'), ex) log.warn( 'tcp_send_fail|error=send_fail_will_retry,address=%s,port=%u,retry=0,request=%s,ex=%s', self._address, self._port, byteshex(request), ex) if not self._connect(): # log.exception('tcp_send_fail|error=retry_reconnect,address=%s,port=%u,retry=0,request=%s', self._address, self._port, request.encode('hex')) log.exception( 'tcp_send_fail|error=retry_reconnect,address=%s,port=%u,retry=0,request=%s', self._address, self._port, byteshex(request)) return False try: self._socket.sendall(packet) return True except Exception as ex: # log.exception('tcp_send_fail|error=retry_send_fail,address=%s,port=%u,retry=1,request=%s', self._address, self._port, request.encode('hex')) log.exception( 'tcp_send_fail|error=retry_send_fail,address=%s,port=%u,retry=1,request=%s', self._address, self._port, byteshex(request)) self.close() return False