def _on_read(self, conn): if conn.status == ConnStatus.Closed: return err = None is_closed = False try: data = conn.sock.recv(1024 * 1024) if data == b'': is_closed = True else: conn.readbuf.extend(data) except Exception as e: if not is_socket_exception_wouldblock(e): err = str(e) while len(conn.readbuf) > 0: head_len = get_message_head_len() if len(conn.readbuf) < head_len: break head_dict = parse_head(conn.readbuf[:head_len]) body_len = head_dict['body_len'] if len(conn.readbuf) < head_len + body_len: break rsp_body = conn.readbuf[head_len:head_len + body_len] del conn.readbuf[:head_len + body_len] self._on_packet(conn, head_dict, Err.Ok.code, '', rsp_body) if is_closed: self.close(conn.conn_id) conn.handler.on_error(conn.conn_id, Err.ConnectionClosed.text) elif err: self.close(conn.conn_id) conn.handler.on_error(conn.conn_id, err)
def _on_read(self, conn: Connection): if conn.status == ConnStatus.Closed: return err = None is_closed = False while True: try: data = conn.sock.recv(1024 * 1024) if data == b'': is_closed = True break else: conn.readbuf.extend(data) except socket.error as e: if e.errno == errno.EAGAIN or e.errno == errno.EWOULDBLOCK: break else: err = e break while len(conn.readbuf) > 0: head_len = get_message_head_len() if len(conn.readbuf) < head_len: break head_dict = parse_head(conn.readbuf[:head_len]) body_len = head_dict['body_len'] if len(conn.readbuf) < head_len + body_len: break rsp_body = conn.readbuf[head_len:head_len + body_len] del conn.readbuf[:head_len + body_len] ret_decrypt, msg_decrypt, rsp_body = decrypt_rsp_body( rsp_body, head_dict, conn.opend_conn_id) if ret_decrypt == RET_OK: rsp_pb = binary2pb(rsp_body, head_dict['proto_id'], head_dict['proto_fmt_type']) else: rsp_pb = None is_sync_rsp = False if conn.sync_req_data is not None: sync_req_head = conn.sync_req_data[0] if head_dict['proto_id'] == sync_req_head[ 'proto_id'] and head_dict[ 'serial_no'] == sync_req_head['serial_no']: conn.sync_rsp_data = (ret_decrypt, msg_decrypt, rsp_pb) conn.sync_req_evt.set() is_sync_rsp = True if not is_sync_rsp: conn.handler.on_packet(conn.conn_id, head_dict['proto_id'], ret_decrypt, msg_decrypt, rsp_pb) if is_closed: conn.handler.on_closed(conn.conn_id) if err: conn.handler.on_error(conn.conn_id, err)
def _parse_req_head(self, req_str): head_len = get_message_head_len() req_head_dict = parse_head(req_str[:head_len]) return req_head_dict
def handle_read(self): # logger.debug("read enter - last_recv_len:{} last_recv_time:{}".format(self.__last_recv_len, self.__last_recv_time)) # self.__last_recv_time = time.time() try: head_len = get_message_head_len() recv_tmp = self.recv(5 * 1024 * 1024) # self.__last_recv_len = len(recv_tmp) # logger.debug("async handle_read len={} head_len={}".format(len(recv_tmp), head_len)) if recv_tmp == b'': return self.__recv_buf += recv_tmp while len(self.__recv_buf) > head_len: head_dict = parse_head(self.__recv_buf[:get_message_head_len()]) body_len = head_dict['body_len'] # 处理完已读数据或者处理时间片超过指定时间 if (body_len + head_len) > len(self.__recv_buf): return rsp_body = self.__recv_buf[head_len: head_len + body_len] self.__recv_buf = self.__recv_buf[head_len + body_len:] # logger.debug("async proto_id = {} rsp_body_len={} body_len={}".format(head_dict['proto_id'],len(rsp_body), body_len)) # 数据解密码校验 ret_decrypt, msg_decrypt, rsp_body = decrypt_rsp_body(rsp_body, head_dict, self._conn_id) if ret_decrypt == RET_OK: proto_id = head_dict['proto_id'] rsp_pb = binary2pb(rsp_body, proto_id, head_dict['proto_fmt_type']) if rsp_pb is None: logger.error("async handle_read not support proto:{} conn_id:{}".format(proto_id, self._conn_id)) else: self.handler_ctx.recv_func(rsp_pb, proto_id) """ if proto_id == ProtoId.Qot_UpdateTicker: # 逐笔分析性能 serial_no = head_dict['serial_no'] tm_s = time.time() self.handler_ctx.recv_func(rsp_pb, proto_id) tm_e = time.time() # logger.debug("async_conn_id={} serial_no={} callback_time={} ".format(self._conn_id, serial_no, tm_e - tm_s)) else: self.handler_ctx.recv_func(rsp_pb, proto_id) """ else: logger.error(msg_decrypt) except Exception as e: if isinstance(e, IOError) and e.errno in [errno.EINTR, errno.EWOULDBLOCK, errno.EAGAIN]: return self.__recv_buf = b'' traceback.print_exc() err = sys.exc_info()[1] + " conn_id:{}".format(self._conn_id) self.handler_ctx.error_func(str(err)) logger.error(err) finally: # logger.debug("read end - time:{}".format(time.time() - self.__last_recv_time)) return
def network_query(self, req_str, is_create_socket=True): """ the function sends req_str to FUTU client and try to get response from the client. :param req_str :return: rsp_str """ req_proto_id = 0 try: is_socket_lock = False ret, msg = self._create_session(is_create_socket) if ret != RET_OK: return ret, msg, None self._socket_lock.acquire() if not self.s: self._socket_lock.release() return RET_ERROR, "socket is closed" is_socket_lock = True head_len = get_message_head_len() req_head_dict = parse_head(req_str[:head_len]) req_proto_id = req_head_dict['proto_id'] req_serial_no = req_head_dict['serial_no'] s_cnt = self.s.send(req_str) is_rsp_body = False left_buf = b'' rsp_body = b'' head_dict = [] while not is_rsp_body: if len(left_buf) < head_len: recv_buf = self.s.recv(5 * 1024 * 1024) if recv_buf == b'': raise Exception( "_SyncNetworkQueryCtx : head recv error, remote server close" ) left_buf += recv_buf head_dict = parse_head(left_buf[:head_len]) rsp_body = left_buf[head_len:] while head_dict['body_len'] > len(rsp_body): try: recv_buf = self.s.recv(5 * 1024 * 1024) rsp_body += recv_buf if recv_buf == b'': raise Exception( "_SyncNetworkQueryCtx : body recv error, remote server close" ) except Exception as e: traceback.print_exc() err = sys.exc_info()[1] error_str = ERROR_STR_PREFIX + str( err ) + ' when receiving after sending %s bytes.' % s_cnt + "" self._force_close_session() return RET_ERROR, error_str, None if head_dict["proto_id"] == req_proto_id and head_dict[ "serial_no"] == req_serial_no: is_rsp_body = True else: left_buf = rsp_body[head_dict['body_len']:] logger.debug( "recv dirty response: req protoID={} serial={}, recv protoID={} serial={} conn_id={}" .format(req_proto_id, req_serial_no, head_dict["proto_id"], head_dict["serial_no"], self._conn_id)) ret_decrypt, msg_decrypt, rsp_body = decrypt_rsp_body( rsp_body, head_dict, self._conn_id) if ret_decrypt != RET_OK: return ret_decrypt, msg_decrypt, None rsp_pb = binary2pb(rsp_body, head_dict['proto_id'], head_dict['proto_fmt_type']) if rsp_pb is None: return RET_ERROR, "parse error", None self._close_session() except Exception as e: traceback.print_exc() err = sys.exc_info()[1] str_proto = ' when req proto:{} conn_id:{}'.format( req_proto_id, self._conn_id) error_str = ERROR_STR_PREFIX + str(err) + str_proto logger.error(error_str) return RET_ERROR, error_str, None finally: if is_socket_lock: self._socket_lock.release() return RET_OK, "", rsp_pb
def handle_read(self): try: # handle_read要控制一下处理时长,避免一直阻塞处理 last_tm = time.time() max_tm = 0.2 head_len = get_message_head_len() recv_tmp = self.recv(5 * 1024 * 1024) # logger.debug("async handle_read len={} head_len={}".format(len(recv_tmp), head_len)) if recv_tmp == b'': return self.__recv_buf += recv_tmp while len(self.__recv_buf) > head_len: head_dict = parse_head( self.__recv_buf[:get_message_head_len()]) body_len = head_dict['body_len'] # 处理完已读数据或者处理时间片超过指定时间 if (body_len + head_len) > len( self.__recv_buf) or (time.time() - last_tm > max_tm): return rsp_body = self.__recv_buf[head_len:head_len + body_len] self.__recv_buf = self.__recv_buf[head_len + body_len:] # logger.debug("async proto_id = {} rsp_body_len={} body_len={}".format(head_dict['proto_id'],len(rsp_body), body_len)) # 数据解密码校验 ret_decrypt, msg_decrypt, rsp_body = decrypt_rsp_body( rsp_body, head_dict, self._conn_id) # debug 时可打开,避免异步推送影响同步请求的调试 """ if head_dict['proto_id'] == ProtoId.InitConnect: ret_decrypt, msg_decrypt, rsp_body = decrypt_rsp_body(rsp_body, head_dict, self._conn_id) else: ret_decrypt, msg_decrypt, rsp_body = -1, "only for debug", None """ if ret_decrypt == RET_OK: rsp_pb = binary2pb(rsp_body, head_dict['proto_id'], head_dict['proto_fmt_type']) if rsp_pb is None: logger.error( "async handle_read not support proto:{} conn_id:{}" .format(head_dict['proto_id'], self._conn_id)) else: self.handler_ctx.recv_func(rsp_pb, head_dict['proto_id']) else: logger.error(msg_decrypt) except Exception as e: if isinstance(e, IOError) and e.errno in [ errno.EINTR, errno.EWOULDBLOCK, errno.EAGAIN ]: return self.__recv_buf = b'' traceback.print_exc() err = sys.exc_info()[1] + " conn_id:{}".format(self._conn_id) self.handler_ctx.error_func(str(err)) logger.debug(err) return