Exemple #1
0
    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)
Exemple #2
0
    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)
Exemple #3
0
 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
Exemple #4
0
    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
Exemple #6
0
    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