增加swagent 接口库
diff --git a/supwisdom/agentlink/__init__.py b/supwisdom/agentlink/__init__.py
new file mode 100644
index 0000000..1c7d390
--- /dev/null
+++ b/supwisdom/agentlink/__init__.py
@@ -0,0 +1,179 @@
+# -*- coding: utf-8
+"""
+agentlink 模块,提供与 swagent 通讯协议的封装
+"""
+import codecs
+import socket
+import struct
+import random
+import time
+import os
+import traceback
+
+__all__ = ['VERSION', 'SWAgentLink']
+
+VERSION = "4.0.0"
+
+
+class SWAgentLink(object):
+ """
+ agentlink 协议封装
+ """
+ MSG_LEN_FMT = '!H'
+ MSG_HEADER_FMT = '!IIIBB'
+ MSG_HEADER_DESC = ('major_version', 'minor_version', 'unique_no', 'msg_type', 'retcode')
+ # 协议版本号定义
+ MAJOR_VERSION = 1
+ MINOR_VERSION = 1
+
+ def __init__(self):
+ self.sock = None
+ self.ip = None
+ self.port = None
+ self.timeout = 10.0
+ self._is_login = False
+ self.unique_no = None
+ self.connection_id = None
+ random.seed(time.time())
+
+ def connect(self, ip, port):
+ self.close()
+ try:
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ sock.settimeout(self.timeout)
+ sock.connect((ip, port))
+ self.sock = sock
+ self.ip = ip
+ self.port = port
+ return True
+ except socket.error:
+ return False
+
+ def login(self):
+ msg_type = 0x30
+ process_id = struct.pack('!I', os.getpid())
+ message_header = self._new_message(msg_type)
+ login_data = self._pack_request(message_header, process_id)
+ data = self._send_and_recv(login_data, 5.0)
+ if not data:
+ return False
+ login_resp = self._unpack_request(data)
+ if not self._check_response(message_header, login_resp):
+ print u"Login response error"
+ return False
+ if login_resp['retcode'] != 0:
+ print u"Login error retcode={0}".format(login_resp['retcode'])
+ return False
+ self.connection_id = login_resp['data']
+ self._is_login = True
+ return True
+
+ def _send_and_recv(self, request, timeout):
+ header_len = struct.calcsize(self.MSG_LEN_FMT)
+ try:
+ self.sock.settimeout(timeout)
+ self.sock.send(request)
+ # print u"Send[{0}]".format(codecs.encode(request, 'hex'))
+ header = self.sock.recv(header_len)
+ if not header:
+ return None
+ body_len = struct.unpack(self.MSG_LEN_FMT, header)[0]
+ body = self.sock.recv(body_len)
+ # print u"Recv[{0}]".format(codecs.encode(body, 'hex'))
+ return body
+ except socket.error as e:
+ print u"socket send and recv error, error: <{0}>".format(e)
+ traceback.print_exc()
+ self.sock.close()
+ self.sock = None
+ self._is_login = False
+ return None
+
+ def get_data(self):
+ msg_type = 0x32
+ message_header = self._new_message(msg_type)
+ req_data = self._pack_request(message_header, self.connection_id)
+ data = self._send_and_recv(req_data, None)
+ if not data:
+ return False
+ getdata_resp = self._unpack_request(data)
+ if not self._check_response(message_header, getdata_resp):
+ print u"get data error"
+ return None
+ if getdata_resp['retcode'] != 0:
+ print u"GetData error retcode={0}".format(getdata_resp['retcode'])
+ return None
+ data = getdata_resp['data']
+ # print codecs.encode(data, 'hex')
+ data_head_len = struct.calcsize('!I')
+ data_len = struct.unpack('!I', data[:data_head_len])[0]
+ if data_len != len(data) - data_head_len:
+ return None
+ return data[data_head_len: data_head_len + data_len]
+
+ def answer_data(self, response):
+ msg_type = 0x34
+ message_header = self._new_message(msg_type)
+ req_data = self._pack_request(message_header, self.connection_id + response)
+ data = self._send_and_recv(req_data, None)
+ answer_resp = self._unpack_request(data)
+ if not self._check_response(message_header, answer_resp):
+ print u"answer data error"
+ return False
+ if answer_resp['retcode'] != 0:
+ print u"Answer error retcode={0}".format(answer_resp['retcode'])
+ return False
+ return True
+
+ def _new_message(self, msg_type):
+ unique_no = random.randint(0x10000000, 0xFFFFFFFF)
+ return dict(major_version=self.MAJOR_VERSION, minor_version=self.MINOR_VERSION,
+ unique_no=unique_no, msg_type=msg_type, retcode=0)
+
+ def _pack_request(self, message_header, data):
+ header = struct.pack(self.MSG_HEADER_FMT, message_header['major_version'],
+ message_header['minor_version'], message_header['unique_no'],
+ message_header['msg_type'], message_header['retcode'])
+ r = []
+ if not data:
+ r.append(struct.pack(self.MSG_LEN_FMT, len(header)))
+ r.append(data)
+ else:
+ r.append(struct.pack(self.MSG_LEN_FMT, (len(header) + len(data))))
+ r.append(header)
+ r.append(data)
+ return ''.join(r)
+
+ def close(self):
+ if self.sock:
+ self.sock.close()
+ self.sock = None
+ self._is_login = False
+
+ def is_ok(self):
+ if not self.sock:
+ return False
+ if not self._is_login:
+ return False
+ return True
+
+ def _unpack_request(self, data):
+ if not data:
+ return None
+ header_len = struct.calcsize(self.MSG_HEADER_FMT)
+ if header_len > len(data):
+ return None
+ resp = struct.unpack(self.MSG_HEADER_FMT, data[:header_len])
+ resp_dict = dict(zip(self.MSG_HEADER_DESC, resp))
+ resp_dict['data'] = data[header_len:]
+ return resp_dict
+
+ def _check_response(self, message_header, response):
+ if not response:
+ return False
+ if (message_header['major_version'] != response['major_version']
+ or message_header['minor_version'] != response['minor_version']
+ or message_header['unique_no'] != response['unique_no']
+ or message_header['msg_type'] != response['msg_type']):
+ return False
+ return True
diff --git a/supwisdom/protocol/webservice.py b/supwisdom/protocol/webservice.py
index 2a1b7a1..f6fd39a 100644
--- a/supwisdom/protocol/webservice.py
+++ b/supwisdom/protocol/webservice.py
@@ -176,6 +176,7 @@
http_request = HTTPRequest(url=self.service_url, method='POST',
headers={'Content-Type': 'application/json'},
connect_timeout=timeout,
+ request_timeout=timeout,
body=self._pack_body(request, timeout))
http_resp = client.fetch(http_request)
except HTTPError, ex: