def parse_message(self, buf): result = parse_meta(buf) if result is None: return None meta_len, pb_msg_len, meta_info = result # try to find the service try: service = self._services[meta_info.service_name] except KeyError: logging.warning('cannot find the service: ' + meta_info.service_name) return None method = service.GetDescriptor().FindMethodByName(meta_info.method_name) if method is None: logging.warning('cannot find the method: ' + meta_info.method_name) return None msg = parse_message(buf[8 + meta_len:8 + meta_len + pb_msg_len], service.GetRequestClass(method)) if msg is None: return None else: return meta_info, service, method, msg
def recv_rsp(self): expected_size = TcpConnection._expected_size pb_buf = self._recv(expected_size) if len(pb_buf) == 0: logging.info('socket has been closed') return False if len(pb_buf) < expected_size: logging.warning('rsp buffer broken') return True if pb_buf[:2] != 'PB': logging.warning('rsp buffer not begin with PB') return True buf_size = struct.unpack("!I", pb_buf[2:])[0] pb_buf = self._recv(buf_size) if len(pb_buf) == 0: logging.info('socket has been closed') return False result = parse_meta(pb_buf, self._recv_meta_info) if result is None: logging.warning('pb decode error, skip this message') return True meta_len, pb_msg_len, meta_info = result if meta_info.flow_id in self._recv_infos: expected_meta, rpc_controller, response_class, done, req_data = \ self._recv_infos[meta_info.flow_id] try: if meta_info.flow_id != expected_meta.flow_id: err_msg = 'rsp flow id not match: %d %d' % (expected_meta.flow_id, meta_info.flow_id) raise TcpConnection.Exception(RpcController.WRONG_FLOW_ID_ERROR, err_msg) elif meta_info.service_name != expected_meta.service_name or \ meta_info.method_name != expected_meta.method_name: err_msg = 'rsp meta not match' raise TcpConnection.Exception(RpcController.WRONG_RSP_META_ERROR, err_msg) elif meta_info.HasField('has_error'): if meta_info.msg_name != TcpConnection._error_msg_name: err_msg = 'rsp meta has error, but with wrong msg name' raise TcpConnection.Exception(RpcController.WRONG_MSG_NAME_ERROR, err_msg) else: response_class = rpc_meta_pb2.ErrorResponse elif meta_info.msg_name != response_class.DESCRIPTOR.full_name: err_msg = 'wrong response class' raise TcpConnection.Exception(RpcController.WRONG_MSG_NAME_ERROR, err_msg) rsp_time = time.time() self._stat.add_rsp_stat(1, rsp_time - req_data.begin_time) rsp = parse_message(pb_buf[8 + meta_len:8 + meta_len + pb_msg_len], response_class) if meta_info.HasField('has_error'): raise TcpConnection.Exception(rsp.err_code, rsp.err_msg) del self._recv_infos[meta_info.flow_id] self._finish_rpc(done, rpc_controller, rsp, req_data.is_async) return True except TcpConnection.Exception as e: rpc_controller.SetFailed((e.err_code, e.err_msg)) logging.warning(e.err_msg) del self._recv_infos[meta_info.flow_id] self._finish_rpc(done, rpc_controller, None, req_data.is_async) return True else: logging.warning('flow id not found: %d' % meta_info.flow_id) return True