def __init__(self): self.header = CwxMsgHeader() self.package = CwxPackage()
class CwxMqPoco: #协议的消息类型定义 #RECV服务类型的消息类型定义 MSG_TYPE_RECV_DATA = 1 #<数据提交消息 MSG_TYPE_RECV_DATA_REPLY = 2 #<数据提交消息的回复 #分发的消息类型定义 MSG_TYPE_SYNC_OUTER_REPORT = 3 #<同步SID点报告消息类型 MSG_TYPE_SYNC_REPORT_REPLY = 4 #<失败返回 MSG_TYPE_SYNC_DATA = 7 MSG_TYPE_SYNC_DATA_REPLY = 8 MSG_TYPE_SYNC_DATA_CHUNK = 9 MSG_TYPE_SYNC_DATA_CHUNK_REPLY = 10 #错误消息 MSG_TYPE_SYNC_ERR = 105 #proxy发送消息 MSG_TYPE_PROXY_RECV_DATA = 20 MSG_TYPE_PROXY_RECV_DATA_REPLY = 21 #proxy订阅消息 MSG_TYPE_PROXY_REPORT = 22 #<读代理同步SID点报告消息类型 MSG_TYPE_PROXY_SYNC_DATA = 24 #同步数据数据 MSG_TYPE_PROXY_SYNC_DATA_REPLY = 25 #同步数据返回 MSG_TYPE_PROXY_SYNC_CHUNK_DATA = 26 #同步chunk数据 MSG_TYPE_PROXY_SYNC_CHUNK_DATA_REPLY = 27 #<同步chunk数据返回 #协议的key定义 KEY_DATA = "d" KEY_RET = "ret" KEY_SID = "sid" KEY_ERR = "err" KEY_TIMESTAMP = "t" KEY_CHUNK = "chunk" KEY_M = "m" KEY_ZIP = "zip" KEY_DELAY = "delay" KEY_TOPIC = "topic" KEY_STATE = "state" KEY_SESSION = "session" KEY_SOURCE = "source" KEY_GROUP = "g" def __init__(self): self.header = CwxMsgHeader() self.package = CwxPackage() def _reset(self): self.package.__init__() self.header.__init__() def __str__(self): package_str = str(self.package) if CwxMsgHeader.check_attr(self.header.attr, CwxMsgHeader.ATTR_COMPRESS): package_str = zlib.compress(package_str) self.header.data_len = len(package_str) return str(self.header) + package_str def parse_header(self, msg_header): ''' @brief 解析消息头,存入self.header中 @return None ''' if len(msg_header) < CwxMsgHeader.HEAD_LEN: print CwxMsgHeader.HEAD_LEN, ' ', len(msg_header) raise BadPackageError() self.header.__init__(msg_header[:CwxMsgHeader.HEAD_LEN]) def pack_mq(self, task_id, data, topic, group, zip=False): ''' @brief 形成mq的一个消息包 @param [in] task_id task-id,回复的时候会返回。 @param [in] data msg的data。 @param [in] group msg的group。 @param [in] user 接收mq的user,若为空,则表示没有用户。 @param [in] passwd 接收mq的passwd,若为空,则表示没有口令。 @param [in] sign 接收的mq的签名类型,若为空,则表示不签名。 @param [in] zip 是否对数据压缩. @return 生成的数据包 ''' self._reset() self.package.data[CwxMqPoco.KEY_DATA] = data self.package.data[CwxMqPoco.KEY_TOPIC] = topic if group != None: self.package.data[CwxMqPoco.KEY_GROUP] = group if zip: self.header.attr = CwxMsgHeader.ATTR_COMPRESS self.header.version = 0 self.header.task_id = task_id self.header.msg_type = CwxMqPoco.MSG_TYPE_PROXY_RECV_DATA return str(self) def parse_package(self, msg): self.package.__init__() self.package = CwxPackage(msg) def parse_mq_reply(self, msg): ''' @brief 解析mq的一个reply消息包 @param [in] msg 接收到的mq消息,不包括msg header。 @return OrderedDict({ret, sid, err)} ret 返回msg的ret。 sid 返回msg的sid。 err 返回msg的err-msg。 ''' self.parse_package(msg) ret = self.package.get_key_int(CwxMqPoco.KEY_RET) if ret == None: raise CwxMqError(CwxMqError.NO_RET, "No key[%s] in recv page." % CwxMqPoco.KEY_RET) sid = 0 if ret != CwxMqError.SUCCESS: err = self.package.get_key(CwxMqPoco.KEY_ERR) if err == None: raise CwxMqError(CwxMqError.NO_ERR, "No key[%s] in recv page." % CwxMqPoco.KEY_ERR) else: err = "" sid = self.package.get_key_int(CwxMqPoco.KEY_SID) if sid == None: raise CwxMqError(CwxMqError.NO_SID,"No key[%s] in recv page." % CwxMqPoco.KEY_SID) return OrderedDict((("ret",ret), ("sid",sid), ("err",err))) def parse_err(self, msg): ''' @brief 解析错误信息 return OrderedDict({ret, err}) ''' self.parse_package(msg) ret = self.package.get_key_int(CwxMqPoco.KEY_RET) if ret == None: raise CwxMqError(CwxMqError.NO_RET, "No key[%s] in recv page." % CwxMqPoco.KEY_RET) err = self.package.get_key(CwxMqPoco.KEY_ERR) if err == None: raise CwxMqError(CwxMqError.NO_ERR,"No key[%s] in recv page." % CwxMqPoco.KEY_ERR) return OrderedDict((("ret",ret), ("err",err))) def pack_sync_report(self, task_id, sid=None, chunk=0,group=None, topic=None, source=None, zip=False): ''' @brief pack mq的report消息包 @param [in] task_id task-id。 @param [in] sid 同步的sid。None表示从当前binlog开始接收 @param [in] chunk chunk的大小,若是0表示不支持chunk,单位为kbyte。 @param [in] zip 接收的mq是否压缩。 @return 生成的数据包 ''' self._reset() if sid != None: self.package.data[CwxMqPoco.KEY_SID] = sid if chunk: self.package.data[CwxMqPoco.KEY_CHUNK] = chunk if group: self.package.data[CwxMqPoco.KEY_GROUP] = group if topic: self.package.data[CwxMqPoco.KEY_TOPIC] = topic if source: self.package.data[CwxMqPoco.KEY_SOURCE] = source if zip: self.package.data[CwxMqPoco.KEY_ZIP] = 1 self.header.msg_type = CwxMqPoco.MSG_TYPE_PROXY_REPORT self.header.task_id = task_id return str(self) def parse_sync_report_reply(self, msg): ''' @brief parse mq的report失败时的reply消息包 @param [in] msg 接收到的mq消息,不包括msg header。 @return OrderedDict({ret, sid, err}) ret report失败的错误代码。 sid report的sid。 err report失败的原因。 ''' self.parse_package(msg) ret = self.package.get_key_int(CwxMqPoco.KEY_SESSION) if ret == None: raise CwxMqError(CwxMqError.NO_RET, "No key[%s] in recv page." % CwxMqPoco.KEY_SESSION) return "session" + str(ret) def parse_sync_data(self, msg): ''' @brief parse mq的sync msg的消息包 @param [in] msg 接收到的mq消息,不包括msg header。 @return [OrderedDict({sid, timestamp, data, group}),...] 返回的list中按顺序包含每条消息。非chunk模式只包含一个消息。 sid 消息的sid。 timestamp 消息接收时的时间。 data 消息的data。 group 消息的group。 ''' self.parse_package(msg) res = [] sid = self.package.get_key_int(CwxMqPoco.KEY_SID) if sid == None: raise CwxMqError(CwxMqError.No_SID, "No key[sid] in recv page.") time_stamp = self.package.get_key_int(CwxMqPoco.KEY_TIMESTAMP) if time_stamp == None: raise CwxMqError(CwxMqError.NO_SID, "No key[t] in recv_page.") topic = self.package.get_key(CwxMqPoco.KEY_TOPIC) if topic == None: raise CwxMqError(CwxMqError.NO_SID, "No key[topic] in recv_page.") data = self.package.get_key(CwxMqPoco.KEY_DATA) if data == None: raise CwxMqError(CwxMqError.NO_SID, "No key[d] in recv_page.") res.append(OrderedDict((("sid",sid), ("timestamp",time_stamp), ("topic",topic), ("data",data)))) return res def pack_sync_data_reply(self, task_id, seq, sid): ''' @brief pack mq的sync msg的消息包的回复 @param [in] task_id task-id。 @param [in] sid 消息的sid。 @return 生成的数据包 ''' self._reset() self.header.msg_type = CwxMqPoco.MSG_TYPE_PROXY_SYNC_DATA_REPLY self.header.task_id = task_id self.header.data_len =16 return str(self.header) + seq + sid def parse_sync_mult_data(self, msg): ''' @brief 解析chunk分发数据 ''' self.parse_package(msg) packages = [] if len(self.package.data) == 1 and CwxMqPoco.KEY_M in self.package.data: msgs = self.package.get_key(CwxMqPoco.KEY_M) if isinstance(msgs, list): for m in self.package.get_key(CwxMqPoco.KEY_M): p = CwxPackage() p.data = m packages.append(p) else: p = CwxPackage() p.data = msgs packages.append(p) else: packages.append(self.package) res = [] for p in packages: sid = p.get_key_int(CwxMqPoco.KEY_SID) if sid == None: raise CwxMqError(CwxMqError.NO_SID, "No key[sid] in recv page.") time_stamp = p.get_key_int(CwxMqPoco.KEY_TIMESTAMP) if time_stamp == None: raise CwxMqError(CwxMqError.NO_SID, "No key[t] in recv_page.") topic = p.get_key(CwxMqPoco.KEY_TOPIC) if topic == None: raise CwxMqError(CwxMqError.NO_SID, "No key[topic] in recv_page.") data = p.get_key(CwxMqPoco.KEY_DATA) if data == None: raise CwxMqError(CwxMqError.NO_SID, "No key[d] in recv_page.") res.append(OrderedDict((("sid",sid), ("timestamp",time_stamp), ("topic",topic), ("data",data)))) return res
class CwxMqPoco: #协议的消息类型定义 #RECV服务类型的消息类型定义 MSG_TYPE_RECV_DATA = 1 #<数据提交消息 MSG_TYPE_RECV_DATA_REPLY = 2 #<数据提交消息的回复 #分发的消息类型定义 MSG_TYPE_SYNC_OUTER_REPORT = 3 #<同步SID点报告消息类型 MSG_TYPE_SYNC_REPORT_REPLY = 4 #<失败返回 MSG_TYPE_SYNC_DATA = 7 MSG_TYPE_SYNC_DATA_REPLY = 8 MSG_TYPE_SYNC_DATA_CHUNK = 9 MSG_TYPE_SYNC_DATA_CHUNK_REPLY = 10 #错误消息 MSG_TYPE_SYNC_ERR = 105 #协议的key定义 KEY_DATA = "d" KEY_RET = "ret" KEY_SID = "sid" KEY_ERR = "err" KEY_TIMESTAMP = "t" KEY_CHUNK = "chunk" KEY_M = "m" KEY_ZIP = "zip" KEY_DELAY = "delay" KEY_TOPIC = "topic" KEY_STATE = "state" KEY_SESSION = "session" KEY_SOURCE = "source" def __init__(self): self.header = CwxMsgHeader() self.package = CwxPackage() def _reset(self): self.package.__init__() self.header.__init__() def __str__(self): package_str = str(self.package) if CwxMsgHeader.check_attr(self.header.attr, CwxMsgHeader.ATTR_COMPRESS): package_str = zlib.compress(package_str) self.header.data_len = len(package_str) return str(self.header) + package_str def parse_header(self, msg_header): ''' @brief 解析消息头,存入self.header中 @return None ''' if len(msg_header) < CwxMsgHeader.HEAD_LEN: print CwxMsgHeader.HEAD_LEN, ' ', len(msg_header) raise BadPackageError() self.header.__init__(msg_header[:CwxMsgHeader.HEAD_LEN]) def pack_mq(self, task_id, data, topic, zip=False): ''' @brief 形成mq的一个消息包 @param [in] task_id task-id,回复的时候会返回。 @param [in] data msg的data。 @param [in] group msg的group。 @param [in] user 接收mq的user,若为空,则表示没有用户。 @param [in] passwd 接收mq的passwd,若为空,则表示没有口令。 @param [in] sign 接收的mq的签名类型,若为空,则表示不签名。 @param [in] zip 是否对数据压缩. @return 生成的数据包 ''' self._reset() self.package.data[CwxMqPoco.KEY_DATA] = data self.package.data[CwxMqPoco.KEY_TOPIC] = topic if zip: self.header.attr = CwxMsgHeader.ATTR_COMPRESS self.header.version = 0 self.header.task_id = task_id self.header.msg_type = CwxMqPoco.MSG_TYPE_RECV_DATA return str(self) def parse_package(self, msg): self.package.__init__() self.package = CwxPackage(msg) def parse_mq_reply(self, msg): ''' @brief 解析mq的一个reply消息包 @param [in] msg 接收到的mq消息,不包括msg header。 @return OrderedDict({ret, sid, err)} ret 返回msg的ret。 sid 返回msg的sid。 err 返回msg的err-msg。 ''' self.parse_package(msg) ret = self.package.get_key_int(CwxMqPoco.KEY_RET) if ret == None: raise CwxMqError(CwxMqError.NO_RET, "No key[%s] in recv page." % CwxMqPoco.KEY_RET) sid = self.package.get_key_int(CwxMqPoco.KEY_SID) if sid == None: raise CwxMqError(CwxMqError.NO_SID, "No key[%s] in recv page." % CwxMqPoco.KEY_SID) if ret != CwxMqError.SUCCESS: err = self.package.get_key(CwxMqPoco.KEY_ERR) if err == None: raise CwxMqError( CwxMqError.NO_ERR, "No key[%s] in recv page." % CwxMqPoco.KEY_ERR) else: err = "" return OrderedDict((("ret", ret), ("sid", sid), ("err", err))) def parse_err(self, msg): ''' @brief 解析错误信息 return OrderedDict({ret, err}) ''' self.parse_package(msg) ret = self.package.get_key_int(CwxMqPoco.KEY_RET) if ret == None: raise CwxMqError(CwxMqError.NO_RET, "No key[%s] in recv page." % CwxMqPoco.KEY_RET) err = self.package.get_key(CwxMqPoco.KEY_ERR) if err == None: raise CwxMqError(CwxMqError.NO_ERR, "No key[%s] in recv page." % CwxMqPoco.KEY_ERR) return OrderedDict((("ret", ret), ("err", err))) def pack_sync_report(self, task_id, sid=None, chunk=0, topic=None, source=None, zip=False): ''' @brief pack mq的report消息包 @param [in] task_id task-id。 @param [in] sid 同步的sid。None表示从当前binlog开始接收 @param [in] chunk chunk的大小,若是0表示不支持chunk,单位为kbyte。 @param [in] zip 接收的mq是否压缩。 @return 生成的数据包 ''' self._reset() if sid != None: self.package.data[CwxMqPoco.KEY_SID] = sid if chunk: self.package.data[CwxMqPoco.KEY_CHUNK] = chunk if topic: self.package.data[CwxMqPoco.KEY_TOPIC] = topic if source: self.package.data[CwxMqPoco.KEY_SOURCE] = source if zip: self.package.data[CwxMqPoco.KEY_ZIP] = 1 self.header.msg_type = CwxMqPoco.MSG_TYPE_SYNC_OUTER_REPORT self.header.task_id = task_id return str(self) def parse_sync_report_reply(self, msg): ''' @brief parse mq的report失败时的reply消息包 @param [in] msg 接收到的mq消息,不包括msg header。 @return OrderedDict({ret, sid, err}) ret report失败的错误代码。 sid report的sid。 err report失败的原因。 ''' self.parse_package(msg) ret = self.package.get_key_int(CwxMqPoco.KEY_SESSION) if ret == None: raise CwxMqError( CwxMqError.NO_RET, "No key[%s] in recv page." % CwxMqPoco.KEY_SESSION) return "session" + str(ret) def parse_sync_data(self, msg): ''' @brief parse mq的sync msg的消息包 @param [in] msg 接收到的mq消息,不包括msg header。 @return [OrderedDict({sid, timestamp, data, group}),...] 返回的list中按顺序包含每条消息。非chunk模式只包含一个消息。 sid 消息的sid。 timestamp 消息接收时的时间。 data 消息的data。 group 消息的group。 ''' self.parse_package(msg) res = [] sid = self.package.get_key_int(CwxMqPoco.KEY_SID) if sid == None: raise CwxMqError(CwxMqError.No_SID, "No key[sid] in recv page.") time_stamp = self.package.get_key_int(CwxMqPoco.KEY_TIMESTAMP) if time_stamp == None: raise CwxMqError(CwxMqError.NO_SID, "No key[t] in recv_page.") topic = self.package.get_key(CwxMqPoco.KEY_TOPIC) if topic == None: raise CwxMqError(CwxMqError.NO_SID, "No key[topic] in recv_page.") data = self.package.get_key(CwxMqPoco.KEY_DATA) if data == None: raise CwxMqError(CwxMqError.NO_SID, "No key[d] in recv_page.") res.append( OrderedDict((("sid", sid), ("timestamp", time_stamp), ("topic", topic), ("data", data)))) return res def pack_sync_data_reply(self, task_id, seq): ''' @brief pack mq的sync msg的消息包的回复 @param [in] task_id task-id。 @param [in] sid 消息的sid。 @return 生成的数据包 ''' self._reset() self.header.msg_type = CwxMqPoco.MSG_TYPE_SYNC_DATA_REPLY self.header.task_id = task_id self.header.data_len = 8 return str(self.header) + seq def parse_sync_mult_data(self, msg): ''' @brief 解析chunk分发数据 ''' self.parse_package(msg) packages = [] if len(self.package.data ) == 1 and CwxMqPoco.KEY_M in self.package.data: msgs = self.package.get_key(CwxMqPoco.KEY_M) if isinstance(msgs, list): for m in self.package.get_key(CwxMqPoco.KEY_M): p = CwxPackage() p.data = m packages.append(p) else: p = CwxPackage() p.data = msgs packages.append(p) else: packages.append(self.package) res = [] for p in packages: sid = p.get_key_int(CwxMqPoco.KEY_SID) if sid == None: raise CwxMqError(CwxMqError.NO_SID, "No key[sid] in recv page.") time_stamp = p.get_key_int(CwxMqPoco.KEY_TIMESTAMP) if time_stamp == None: raise CwxMqError(CwxMqError.NO_SID, "No key[t] in recv_page.") topic = p.get_key(CwxMqPoco.KEY_TOPIC) if topic == None: raise CwxMqError(CwxMqError.NO_SID, "No key[topic] in recv_page.") data = p.get_key(CwxMqPoco.KEY_DATA) if data == None: raise CwxMqError(CwxMqError.NO_SID, "No key[d] in recv_page.") res.append( OrderedDict((("sid", sid), ("timestamp", time_stamp), ("topic", topic), ("data", data)))) return res
class CwxMqPoco: # 协议的消息类型定义 # RECV服务类型的消息类型定义 MSG_TYPE_MQ = 1 # <数据提交消息 MSG_TYPE_MQ_REPLY = 2 # <数据提交消息的回复 MSG_TYPE_MQ_COMMIT = 3 # <数据commit消息 MSG_TYPE_MQ_COMMIT_REPLY = 4 # <commit消息的回复 # 分发的消息类型定义 MSG_TYPE_SYNC_REPORT = 5 # <同步SID点报告消息类型 MSG_TYPE_SYNC_REPORT_REPLY = 6 # <失败返回 MSG_TYPE_SYNC_DATA = 7 MSG_TYPE_SYNC_DATA_REPLY = 8 # MQ Fetch服务类型的消息类型定义 MSG_TYPE_FETCH_DATA = 9 # <数据获取消息类型 MSG_TYPE_FETCH_DATA_REPLY = 10 # <回复数据获取消息类型 MSG_TYPE_FETCH_COMMIT = 11 # <commit 获取的消息 MSG_TYPE_FETCH_COMMIT_REPLY = 12 # <reply commit的消息 # 创建mq queue消息 MSG_TYPE_CREATE_QUEUE = 100 # <创建MQ QUEUE的消息类型 MSG_TYPE_CREATE_QUEUE_REPLY = 101 # <回复创建MQ QUEUE的消息类型 # 删除mq queue消息 MSG_TYPE_DEL_QUEUE = 102 # <删除MQ QUEUE的消息类型 MSG_TYPE_DEL_QUEUE_REPLY = 103 # <回复删除MQ QUEUE的消息类型 # binlog内部的sync binlogleixing GROUP_SYNC = 0xFFFFFFFF # 协议的key定义 KEY_DATA = "data" KEY_RET = "ret" KEY_SID = "sid" KEY_ERR = "err" KEY_BLOCK = "block" KEY_TIMESTAMP = "timestamp" KEY_USER = "******" KEY_PASSWD = "passwd" KEY_SUBSCRIBE = "subscribe" KEY_QUEUE = "queue" KEY_GROUP = "group" KEY_CHUNK = "chunk" KEY_WINDOW = "window" KEY_M = "m" KEY_SIGN = "sign" KEY_CRC32 = "crc32" KEY_MD5 = "md5" KEY_NAME = "name" KEY_AUTH_USER = "******" KEY_AUTH_PASSWD = "auth_passwd" KEY_COMMIT = "commit" KEY_TIMEOUT = "timeout" KEY_DEF_TIMEOUT = "def_timeout" KEY_MAX_TIMEOUT = "max_timeout" KEY_COMMIT = "commit" KEY_UNCOMMIT = "uncommit" KEY_ZIP = "zip" KEY_DELAY = "delay" def __init__(self): self.header = CwxMsgHeader() self.package = CwxPackage() def _reset(self): self.package.__init__() self.header.__init__() def __str__(self): package_str = str(self.package) if CwxMsgHeader.check_attr(self.header.attr, CwxMsgHeader.ATTR_COMPRESS): package_str = zlib.compress(package_str) self.header.data_len = len(package_str) return str(self.header) + package_str def parse_header(self, msg_header): """ @brief 解析消息头,存入self.header中 @return None """ if len(msg_header) < CwxMsgHeader.HEAD_LEN: raise BadPackageError() self.header.__init__(msg_header[: CwxMsgHeader.HEAD_LEN]) def pack_mq(self, task_id, data, group, user=None, passwd=None, sign=None, zip=False): """ @brief 形成mq的一个消息包 @param [in] task_id task-id,回复的时候会返回。 @param [in] data msg的data。 @param [in] group msg的group。 @param [in] user 接收mq的user,若为空,则表示没有用户。 @param [in] passwd 接收mq的passwd,若为空,则表示没有口令。 @param [in] sign 接收的mq的签名类型,若为空,则表示不签名。 @param [in] zip 是否对数据压缩. @return 生成的数据包 """ self._reset() self.package.data[CwxMqPoco.KEY_DATA] = data self.package.data[CwxMqPoco.KEY_GROUP] = group if user: self.package.data[CwxMqPoco.KEY_USER] = user if passwd: self.package.data[CwxMqPoco.KEY_PASSWD] = passwd if sign == CwxMqPoco.KEY_CRC32: crc = binascii.crc32(str(self.package)) self.package.data[CwxMqPoco.KEY_CRC32] = struct.pack("i", crc) else: if sign == CwxMqPoco.KEY_MD5: self.package.data[CwxMqPoco.KEY_MD5] = hashlib.md5(str(self.package)).digest() if zip: self.header.attr = CwxMsgHeader.ATTR_COMPRESS self.header.version = 0 self.header.task_id = task_id self.header.msg_type = CwxMqPoco.MSG_TYPE_MQ return str(self) def parse_package(self, msg): self.package.__init__() self.package = CwxPackage(msg) crc = self.package.get_key(CwxMqPoco.KEY_CRC32) if crc: crc = struct.unpack("i", crc)[0] del self.package.data[CwxMqPoco.KEY_CRC32] cal_crc = binascii.crc32(str(self.package)) if crc != cal_crc: raise CwxMqError( CwxMqError.INVALID_CRC32, "CRC32 signture error. recv signture:%x, local signture:%x" % (crc & 0xFFFFFFFF, cal_crc & 0xFFFFFFFF), ) md5 = self.package.get_key(CwxMqPoco.KEY_MD5) if md5: del self.package.data[CwxMqPoco.KEY_MD5] cal_md5 = hashlib.md5(str(self.package)).digest() if md5 != cal_md5: raise CwxMqError( CwxMqError.INVALID_MD5, "MD5 signture error. recv signture:%s, local signture:%s" % (binascii.b2a_hex(md5), binascii.b2a_hex(cal_md5)), ) def parse_mq_reply(self, msg): """ @brief 解析mq的一个reply消息包 @param [in] msg 接收到的mq消息,不包括msg header。 @return OrderedDict({ret, sid, err)} ret 返回msg的ret。 sid 返回msg的sid。 err 返回msg的err-msg。 """ self.parse_package(msg) ret = self.package.get_key_int(CwxMqPoco.KEY_RET) if ret == None: raise CwxMqError(CwxMqError.NO_RET, "No key[%s] in recv page." % CwxMqPoco.KEY_RET) sid = self.package.get_key_int(CwxMqPoco.KEY_SID) if sid == None: raise CwxMqError(CwxMqError.NO_SID, "No key[%s] in recv page." % CwxMqPoco.KEY_SID) if ret != CwxMqError.SUCCESS: err = self.package.get_key(CwxMqPoco.KEY_ERR) if err == None: raise CwxMqError(CwxMqError.NO_ERR, "No key[%s] in recv page." % CwxMqPoco.KEY_ERR) else: err = "" return OrderedDict((("ret", ret), ("sid", sid), ("err", err))) def pack_commit(self, task_id, user=None, passwd=None): """ @brief pack mq的commit消息包 @param [in] task_id 消息的task-id。 @param [in] user 接收的mq的user,若为空,则表示没有用户。 @param [in] passwd 接收的mq的passwd,若为空,则表示没有口令。 @return 生成的数据包 """ self._reset() if user: self.package.data[CwxMqPoco.KEY_USER] = user if passwd: self.package.data[CwxMqPoco.KEY_PASSWD] = passwd self.header.msg_type = CwxMqPoco.MSG_TYPE_MQ_COMMIT self.header.task_id = task_id return str(self) def parse_commit_reply(self, msg): """ @brief 解析mq的一个commit reply消息包 @param [in] msg 接收到的mq消息,不包括msg header。 @return OrderedDict({ret, err}) ret 执行状态码。 err 执行失败时的错误消息。 """ self.parse_package(msg) ret = self.package.get_key_int(CwxMqPoco.KEY_RET) if ret == None: raise CwxMqError(CwxMqError.NO_RET, "No key[%s] in recv page." % CwxMqPoco.KEY_RET) if CwxMqError.SUCCESS != ret: err_msg = self.package.get_key(CwxMqPoco.KEY_ERR) if err_msg == None: raise CwxMqError(CwxMqError.NO_ERR, "No key[%s] in recv page." % CwxMqPoco.KEY_ERR) else: err_msg = "" return OrderedDict((("ret", ret), ("err", err_msg))) def pack_sync_report( self, task_id, sid=None, chunk=0, subscribe=None, user=None, passwd=None, sign=None, zip=False ): """ @brief pack mq的report消息包 @param [in] task_id task-id。 @param [in] sid 同步的sid。None表示从当前binlog开始接收 @param [in] chunk chunk的大小,若是0表示不支持chunk,单位为kbyte。 @param [in] subscribe 订阅的消息类型。 @param [in] user 接收的mq的user,若为空,则表示没有用户。 @param [in] passwd 接收的mq的passwd,若为空,则表示没有口令。 @param [in] sign 接收的mq的签名类型,若为空,则表示不签名。 @param [in] zip 接收的mq是否压缩。 @return 生成的数据包 """ self._reset() if sid != None: self.package.data[CwxMqPoco.KEY_SID] = sid if chunk: self.package.data[CwxMqPoco.KEY_CHUNK] = chunk if subscribe: self.package.data[CwxMqPoco.KEY_SUBSCRIBE] = subscribe if user: self.package.data[CwxMqPoco.KEY_USER] = user if passwd: self.package.data[CwxMqPoco.KEY_PASSWD] = passwd if sign: self.package.data[CwxMqPoco.KEY_SIGN] = sign if zip: self.package.data[CwxMqPoco.KEY_ZIP] = 1 self.header.msg_type = CwxMqPoco.MSG_TYPE_SYNC_REPORT self.header.task_id = task_id return str(self) def parse_sync_report_reply(self, msg): """ @brief parse mq的report失败时的reply消息包 @param [in] msg 接收到的mq消息,不包括msg header。 @return OrderedDict({ret, sid, err}) ret report失败的错误代码。 sid report的sid。 err report失败的原因。 """ return self.parse_mq_reply(msg) def pack_fetch_mq(self, block, queue_name, user=None, passwd=None, timeout=0): """ @brief pack mq的fetch msg的消息包 *@param [in] block 在没有消息的时候是否block,1:是;0:不是。 *@param [in] queue_name 队列的名字。 *@param [in] user 接收的mq的user,若为空,则表示没有用户。 *@param [in] passwd 接收的mq的passwd,若为空,则表示没有口令。 *@param [in] timeout commit队列的超时时间,若为0表示采用默认超时时间,单位为s。 *@return 生成的数据包 """ self._reset() self.package.data[CwxMqPoco.KEY_BLOCK] = block if queue_name: self.package.data[CwxMqPoco.KEY_QUEUE] = queue_name if user: self.package.data[CwxMqPoco.KEY_USER] = user if passwd: self.package.data[CwxMqPoco.KEY_PASSWD] = passwd if timeout: self.package.data[CwxMqPoco.KEY_TIMEOUT] = timeout self.header.msg_type = CwxMqPoco.MSG_TYPE_FETCH_DATA return str(self) def parse_fetch_mq_reply(self, msg): """ @brief parse mq的fetch msg的reply消息包 @param [in] msg 接收到的mq消息,不包括msg header。 @return OrderedDict({ret, err, sid, timestamp, data, group}) ret 获取mq消息的状态码。 err 状态不是CWX_MQ_ERR_SUCCESS的错误消息。 sid 成功时,返回消息的sid。 timestamp 成功时,返回消息的时间戳。 data 成功时,返回消息的data。 group 成功时,返回消息的group。 """ self.parse_package(msg) ret = self.package.get_key_int(CwxMqPoco.KEY_RET) if ret == None: raise CwxMqError(CwxMqError.NO_RET, "No key[%s] in recv page." % CwxMqPoco.KEY_RET) if CwxMqError.SUCCESS != ret: err_msg = self.package.get_key(CwxMqPoco.KEY_ERR) if err_msg == None: raise CwxMqError(CwxMqError.NO_ERR, "No key[%s] in recv page." % CwxMqPoco.KEY_ERR) else: err_msg = "" sid = self.package.get_key_int(CwxMqPoco.KEY_SID) if sid == None: raise CwxMqError(CwxMqError.NO_SID, "No key[%s] in recv page." % CwxMqPoco.KEY_SID) time_stamp = self.package.get_key_int(CwxMqPoco.KEY_TIMESTAMP) if time_stamp == None: raise CwxMqError(CwxMqError.NO_TIMESTAMP, "No key[%s] in recv page." % CwxMqPoco.KEY_TIMESTAMP) if CwxMqPoco.KEY_DATA in self.package.data: data = self.package.get_key(CwxMqPoco.KEY_DATA) else: raise CwxMqError(CwxMqError.NO_KEY_DATA, "No key[%s] in recv page." % CwxMqPoco.KEY_DATA) group = self.package.get_key_int(CwxMqPoco.KEY_GROUP) or 0 return OrderedDict( (("ret", ret), ("err", err_msg), ("sid", sid), ("timestamp", time_stamp), ("data", data), ("group", group)) ) def pack_fetch_mq_commit(self, commit, delay): """ @brief pack commit类型队列的commit消息 @param [in] commit 是否commit。1:commit;0:取消commit @param [in] delay uncommit是,delay的秒数。 @return 生成的数据包 """ self._reset() self.package.data[CwxMqPoco.KEY_COMMIT] = commit self.package.data[CwxMqPoco.KEY_DELAY] = delay self.header.msg_type = CwxMqPoco.MSG_TYPE_FETCH_COMMIT return str(self) def parse_fetch_mq_commit_reply(self, msg): """ @brief parse commit类型队列的commit reply消息 @param [in] msg 接收到的mq消息,不包括msg header。 @return OrderedDict({ret, err}) ret commit的返回code err commit失败时的错误消息 """ return self.parse_commit_reply(msg) def pack_create_queue( self, name, user, passwd, scribe, auth_user, auth_passwd, sid, commit, def_time_out=0, max_time_out=0 ): """ @brief pack create queue的消息 @param [in] name 队列的名字 @param [in] user 队列的用户名 @param [in] passwd 队列的用户口令 @param [in] scribe 队列的消息订阅规则 @param [in] auth_user mq监听的用户名 @param [in] auth_passwd mq监听的用户口令 @param [in] sid 队列开始的sid,若为0,则采用当前最大的sid @param [in] commit 是否为commit类型的队列,1:是,0:不是。 @param [in] def_time_out 消息队列的缺省超时时间,若是0,则采用系统默认缺省超时时间。单位为s。 @param [in] max_time_out 消息队列的最大超时时间,若是0,则采用系统默认最大超时时间。单位为s。 @return 生成的数据包 """ self._reset() self.package.data[CwxMqPoco.KEY_NAME] = name self.package.data[CwxMqPoco.KEY_USER] = user self.package.data[CwxMqPoco.KEY_PASSWD] = passwd self.package.data[CwxMqPoco.KEY_SUBSCRIBE] = scribe self.package.data[CwxMqPoco.KEY_AUTH_USER] = auth_user self.package.data[CwxMqPoco.KEY_AUTH_PASSWD] = auth_passwd self.package.data[CwxMqPoco.KEY_SID] = sid self.package.data[CwxMqPoco.KEY_COMMIT] = commit self.package.data[CwxMqPoco.KEY_DEF_TIMEOUT] = def_time_out self.package.data[CwxMqPoco.KEY_MAX_TIMEOUT] = max_time_out self.header.msg_type = CwxMqPoco.MSG_TYPE_CREATE_QUEUE return str(self) def parse_create_queue_reply(self, msg): """ @brief parse create队列的reply消息 @param [in] msg 接收到的mq消息,不包括msg header。 @return OrderedDict({ret, err}) ret commit的返回code err 失败时的错误消息 """ return self.parse_commit_reply(msg) def pack_del_queue(self, name, user, passwd, auth_user, auth_passwd): """ @brief pack delete queue的消息 @param [in] name 队列的名字 @param [in] user 队列的用户名 @param [in] passwd 队列的用户口令 @param [in] auth_user mq监听的用户名 @param [in] auth_passwd mq监听的用户口令 @return 生成的数据包 """ self._reset() self.package.data[CwxMqPoco.KEY_NAME] = name self.package.data[CwxMqPoco.KEY_USER] = user self.package.data[CwxMqPoco.KEY_PASSWD] = passwd self.package.data[CwxMqPoco.KEY_AUTH_USER] = auth_user self.package.data[CwxMqPoco.KEY_AUTH_PASSWD] = auth_passwd self.header.msg_type = CwxMqPoco.MSG_TYPE_DEL_QUEUE return str(self) def parse_del_queue_reply(self, msg): """ *@brief parse delete队列的reply消息 @param [in] msg 接收到的mq消息,不包括msg header。 @return (ret, err) ret commit的返回code err 失败时的错误消息 """ return self.parse_commit_reply(msg) def parse_sync_data(self, msg): """ @brief parse mq的sync msg的消息包 @param [in] msg 接收到的mq消息,不包括msg header。 @return [OrderedDict({sid, timestamp, data, group}),...] 返回的list中按顺序包含每条消息。非chunk模式只包含一个消息。 sid 消息的sid。 timestamp 消息接收时的时间。 data 消息的data。 group 消息的group。 """ self.parse_package(msg) packages = [] if len(self.package.data) == 1 and CwxMqPoco.KEY_M in self.package.data: msgs = self.package.get_key(CwxMqPoco.KEY_M) if isinstance(msgs, list): for m in self.package.get_key(CwxMqPoco.KEY_M): p = CwxPackage() p.data = m packages.append(p) else: p = CwxPackage() p.data = msgs packages.append(p) else: packages.append(self.package) res = [] for p in packages: sid = p.get_key_int(CwxMqPoco.KEY_SID) if sid == None: raise CwxMqError(CwxMqError.NO_SID, "No key[%s] in recv page." % CwxMqPoco.KEY_SID) time_stamp = p.get_key_int(CwxMqPoco.KEY_TIMESTAMP) if time_stamp == None: raise CwxMqError(CwxMqError.NO_TIMESTAMP, "No key[%s] in recv page." % CwxMqPoco.KEY_TIMESTAMP) if CwxMqPoco.KEY_DATA in p.data: data = p.get_key(CwxMqPoco.KEY_DATA) else: raise CwxMqError(CwxMqError.NO_KEY_DATA, "No key[%s] in recv page." % CwxMqPoco.KEY_DATA) group = p.get_key_int(CwxMqPoco.KEY_GROUP) or 0 res.append(OrderedDict((("sid", sid), ("timestamp", time_stamp), ("data", data), ("group", group)))) return res def pack_sync_data_reply(self, task_id, sid): """ @brief pack mq的sync msg的消息包的回复 @param [in] task_id task-id。 @param [in] sid 消息的sid。 @return 生成的数据包 """ self._reset() self.package.data[CwxMqPoco.KEY_SID] = sid self.header.msg_type = CwxMqPoco.MSG_TYPE_SYNC_DATA_REPLY self.header.task_id = task_id return str(self)