def _send_run_method_response_data_to_client(in_conn, in_sequence_id, rc_status_flag, in_result_data): """ 给客户端回method执行响应 """ if rc_status_flag: #构建返回XML数据 #RUN MENTHOD SUC out_data = ConstructResponseData.construct_response_data( in_sequence_id, ClientResponseHandle.RESPONSE_STATUS_SUC, in_result_data) ClientResponseHandle.send_response_data_to_client( in_conn, out_data) else: #构建返回XML数据 #RUN MENTHOD EXCEPT out_data = ConstructResponseData.construct_response_data( in_sequence_id, ClientResponseHandle.RESPONSE_STATUS_FAILE, in_result_data) ClientResponseHandle.send_response_data_to_client( in_conn, out_data)
def insert_method_sequence_obj(in_sequence, in_conn): """ 添加对消息唯一标示进行处理 """ #启动MethodSequence节点时效性管理线程 start_method_sequence_object_management_thread() #查找in_sequence是否纯正处理对象 sequence_obj_handle = MethodSequenceManagement.get_method_sequence_obj_handle( in_sequence) if None != sequence_obj_handle: log_out("Sequence ID:%s" % in_sequence) #获取消息的状态 sequence_obj_status = sequence_obj_handle.get_sequence_status() if (MethodSequence.METHOD_SEQUENCE_INIT == sequence_obj_status or MethodSequence.METHOD_SEQUENCE_TRY == sequence_obj_status): log_out( "Sequence object(%s) is exist, method status is METHOD_SEQUENCE_INIT or METHOD_SEQUENCE_TRY" % in_sequence) #更新消息的状态为TRY,INIT之后并没有得到处理结果 sequence_obj_handle.set_sequence_status_to_try(in_conn) #不再向下传递消息请求 return False elif (MethodSequence.METHOD_SEQUENCE_FINISH == sequence_obj_status or MethodSequence.METHOD_SEQUENCE_CONN_LOSE == sequence_obj_status): log_out( "Sequence object(%s) is exist, response buf finish data to client" % in_sequence) #直接回复客户端消息处理结果 sequence_obj_reponse_data = sequence_obj_handle.get_sequence_response_data( ) from outputcontrol import ClientResponseHandle ClientResponseHandle.write_data_to_client( in_conn, sequence_obj_reponse_data) #不再向下传递消息请求 return False else: log_out("Create sequence object, sequence=%s" % in_sequence) #创建新的消息对象,并保存到列表中 sequence_obj_handle = MethodSequenceManagement.new_method_sequence_obj( in_sequence, in_conn) #继续向下分发消息处理 return True
def _dispath_top_request(): """ 下发消息到处理线程接口 """ try: #获取存在的request处理线程对象总数 temp_request_control_thread_total_count=DispathMethodRequest.get_method_request_control_thread_total_count() #获取空闲的request处理线程对象总数,当有处理线程空闲时,直接下发消息节点 temp_request_control_thread_idle_count=DispathMethodRequest.get_method_request_control_thread_idle_count() #存在空闲的request处理线程对象,直接下发消息节点 if temp_request_control_thread_idle_count>0: log.debug_info("Dispath client request to idle control thread") #获取客户端消息节点缓存队列最前面的消息节点 client_request_node=MethodNodeManagement.\ pop_client_request_node_from_wait_run_buffer_list() if not client_request_node: log.debug_info("BUFLIST: Not exist waiting method request") return False #存在空闲的request处理线程对象,直接下发消息节点到该对象 DispathMethodRequest.dispath_method_request_to_control_thread(client_request_node) return True elif temp_request_control_thread_total_count<OPEN_CONTROL_THREAD_MAX_COUNT: log.debug_info("Create new thread and dispath messages to the object") #获取客户端消息节点缓存队列最前面的消息节点 client_request_node=MethodNodeManagement.\ pop_client_request_node_from_wait_run_buffer_list() if not client_request_node: log.debug_info("BUFLIST: Not exist waiting method request") return False #request线程对象都处于忙状态或者不存在request线程对象,创建新的处理线程节点并直接下发消息节点到该对象 DispathMethodRequest.dispath_method_request_to_control_thread(client_request_node) return True except Exception, e: err_info = "Dispath client request to idle control thread occurs expection: %s" % e log.debug_err(err_info) #返回错误消息 in_conn_handle=client_request_node.get_client_conn_handle() ClientResponseHandle.send_error_info_data_to_client(in_conn_handle,err_info)
def send_response_data_to_sequence_obj_other_conn_handle( in_conn_list, in_response_data): """ 将响应结果发送给消息ID的其他重复的连接 """ log_out( "send_response_data_to_sequence_obj_other_conn_handle start, in_conn_list count=%d" % len(in_conn_list)) for conn in in_conn_list: #通过Client连接句柄发送响应数据到连接客户端 from outputcontrol import ClientResponseHandle ClientResponseHandle.write_data_to_client(conn, in_response_data) log_out("send_response_data_to_sequence_obj_other_conn_handle end")
def handle_message(self, message): """ 处理消息 """ #log.debug_info("Recv total data:%s\n" % message) try: #解析消息体数据 tmp_sequence, \ tmp_method_name, \ tmp_cpe_id, \ tmp_method_parameters_list=ParseRecvData.parse_recv_data(message) except Exception, e: #解析消息体数据异常 err_info = "Parse recv message data occurs expection: %s" % e log.debug_err(err_info) #返回错误消息 ClientResponseHandle.send_error_info_data_to_client( self.conn, err_info) return False
def set_method_request_control_thread_management_property_data(in_thread_handle,in_method_data): """ 更新请求处理method相关数据内容 """ if not in_thread_handle: return False #更新请求处理method相关数据内容 temp_push_data_suc_flag=in_thread_handle.push_request_method_data_to_property(in_method_data) #数据处理对象句柄无效,错误处理 if not temp_push_data_suc_flag: err_info = "Dispath method request to control thread fail. Method control object handle is Invalid." log.debug_err(err_info) #返回错误消息 in_conn_handle=in_method_data.get_client_conn_handle() ClientResponseHandle.send_error_info_data_to_client(in_conn_handle,err_info) return False return True
class MethodAgentServer(object): """ TCP SOCKET服务器,处理来自TCL客户端发送的连接请求,同时将请求的处理分发给子进程处理。 """ def __init__(self, addr='localhost', port=50000): """ 初始化 """ self.addr = addr # listen addr self.port = port # listen port self.sock = None # socket server object def start_socket_server(self): """ 启动TCP连接服务器,处理来自TCL客户端发送的连接请求,同时将请求的处理分发给子进程处理。 """ #检查SOCKET连接对象是否存在,如果存在则端口连接,并且重置SOCKET句柄。 if self.sock: self.sock.close() self.sock = None #创建TCP SOCKET 服务器。 try: self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.bind((self.addr, self.port)) self.sock.listen(MAX_LISTEM_CONNECT_NUMBER) except Exception, e: err_info = "Create socket server occurs exception:%s" % e log.debug_err(err_info) return log.debug_info("Socket server is start!") while 1: log.debug_info("Socket server:wait for client connection...") try: #阻塞等待客户端触发连接请求 connection, address = self.sock.accept() log.debug_info("Socket server:accept client client connection") #更新连接接句柄总数,接收到一个client连接,接接句柄总数加一 ClientConnectCount.updata_tcp_client_count_value(True) log.debug_info("Client connected handle count number=%d" % ClientConnectCount.get_tcp_client_count()) except Exception, e: err_info = "Socket server accept occurs exception: %s" % e log.debug_err(err_info) break #接受一个连接 try: #创建线程处理Client发送的消息数据 thread_i = AcceptClientConnectControlThread( connection, address) thread_i.start() except Exception, e: #启动处理线程异常 err_info = "Start accept client connect control thread occurs exception:%s" % e log.debug_err(err_info) #返回错误消息并继续等待其他客户端的连接 ClientResponseHandle.send_error_info_data_to_client( connection, err_info) continue
def handle_listen_keepalive(self): time.sleep(3) log.debug_info("Recv client keepalive data Begin") #心跳包数据处理 #3分钟没有收到心跳,表示客户端连接断开,退出循环接收心跳数据包循环 error_keepalive_count = 0 #初始化等待第一个心跳包的开始时间 wait_recv_keepalive_time_object = datetime.datetime.now() #循环接收心跳数据包 while 1: #获取当前系统时间 temp_current_time_object = datetime.datetime.now() #检查心跳包间隔时间是否超出 time_difference_seconds = (temp_current_time_object - wait_recv_keepalive_time_object).seconds #3分钟没有收到心跳,表示客户端连接断开,退出循环接收心跳数据包循环 if time_difference_seconds >= ( int)(CLIETN2SERVER_KEEPALIVE_INVALID_TIME_LENGTH): log.debug_info("Client keepalive invalid, connection lost") break try: #开始接收心跳包数据 data = self.conn.recv(MAX_ONE_RECV_BUF_LENGTH) #log.debug_info( "Recv keepalive data=%s\n" % data ) except Exception, e: #主动断开客户端连接或者客户端强制断开连接 log.debug_info("Recv keepalive data occurs error:%s\n" % e) break #通过数据分隔符分隔心跳包数据 data_item_list = data.split(MESSAGE_TOTAL_LENGTH_DATA_SPLIT_STRING) print data_item_list if len(data_item_list) >= 2: data_keepalive_length = data_item_list[0] data_keepalive_string = data_item_list[1] if (int(data_keepalive_length) == len(data_keepalive_string) and data_keepalive_string == CLIETN2SERVER_KEEPALIVE_DATA): log.debug_info("Read keepalive data SUC") #更新最后一次接收到心跳的时间 wait_recv_keepalive_time_object = datetime.datetime.now() #发送心跳响应到客户端 ClientResponseHandle.write_keepalive_data_to_client( self.conn, SERVER2CLIETN_KEEPALIVE_DATA) else: #解析消息失败,不匹配数据规则,丢弃此消息 log.debug_info( "Read keepalive data total length occurs error, drop this message!" ) else: #解析消息失败,不匹配数据规则,丢弃此消息 log.debug_info( "Read keepalive data total length occurs error, drop this message!" ) time.sleep(20)
class AcceptClientConnectControlThread(threading.Thread): """ 对Client发送的消息数据处理 """ def __init__(self, conn, addr): """ 初始化 """ threading.Thread.__init__(self) self.conn = conn # 保存Client的连接句柄 self.addr = addr # 保存Client的连接地址 def run(self): """ 接收Client发送的消息数据,并且做初步解析,将消息请求分发到具体的消息处理模块 """ log.debug_info( "\nClient connection request from address=%s,client port=%d" % (self.addr[0], self.addr[1])) data_all = None time_out_try_count = 3 log.debug_info("Begin recv data.") #接收第一个BUG MAX_ONE_RECV_BUF_LENGTH长度的数据 data = self.conn.recv(MAX_ONE_RECV_BUF_LENGTH) log.debug_info("\nRecv data buffer length=%d\n" % len(data)) #从第一个BUG中读取消息的有效数据长度 message_total_length, split_data_pos = self.get_message_total_length( data) if (message_total_length > 0 and split_data_pos < len(data)): #保存接收到的数据 data_all = data[split_data_pos:] #检查是否有更多的数据需要接收 self.conn.settimeout(RECV_TIMEOUT_LENGTH) while 1: #检查消息是否接收完成 if (len(data_all)) >= message_total_length: log.debug_info("Recv data complete.") log.debug_info("Recv total data:%s\n" % data_all) break try: data = self.conn.recv(MAX_ONE_RECV_BUF_LENGTH) # 检查数据长度 if len(data): log.debug_info("\nRecv data buffer length=%d\n" % len(data)) #保存接收到的数据 data_all += data else: continue except socket.timeout, e: if time_out_try_count > 0: time_out_try_count = time_out_try_count - 1 log.debug_info("Reset recv data timeout length") self.conn.settimeout(RECV_TIMEOUT_LENGTH) continue else: log.debug_err("Recv data timeout") break except Exception, e: err_info = "Recv data occurs exception:%s" % e log.debug_err(err_info) break self.conn.settimeout(None) log.debug_info( "\nmessage total length=%d, split_data_pos=%d, data_all=%d\n" % (message_total_length, split_data_pos, len(data_all))) #检查消息是否接收完成 if (len(data_all)) != message_total_length: #接收消息数据不完整,丢弃此消息 err_info = "Recv message occurs error, drop this message!" #返回错误消息 ClientResponseHandle.send_error_info_data_to_client( self.conn, err_info) else: #下发消息到消息处理流程 message = data_all self.handle_message(message) #心跳包数据处理 #3个心跳时间长度没有收到心跳,表示客户端连接断开,不在发送数据结果 self.handle_listen_keepalive()
self.conn, err_info) else: #下发消息到消息处理流程 message = data_all self.handle_message(message) #心跳包数据处理 #3个心跳时间长度没有收到心跳,表示客户端连接断开,不在发送数据结果 self.handle_listen_keepalive() else: #获取消息头消息总长度数据失败,丢弃此消息 err_info = "Read message data total length occurs error, drop this message!" #返回错误消息 ClientResponseHandle.send_error_info_data_to_client( self.conn, err_info) def get_message_total_length(self, in_message_head): """ 取消息体有效数据长度 """ message_total_length = 0 split_data_pos = 0 #取消息体有效数据长度 split_pos = in_message_head.find( MESSAGE_TOTAL_LENGTH_DATA_SPLIT_STRING) if split_pos: message_len_str = in_message_head[0:split_pos]
def dispath_method_request_to_control_thread(in_method_data): """ 将method分发到空闲的线程去处理 """ global client_request_control_thread_object_list global client_request_control_thread_object_list_lock try: client_request_control_thread_object_list_lock.acquire() thread_object_count=len(client_request_control_thread_object_list) client_request_control_thread_object_list_lock.release() if 0 == thread_object_count:#len(client_request_control_thread_object_list): log.debug_info("New Method Request Control Thread and start run thread") #创建新的处理线程,并将消息分发到该线程 thread_node=_MethodRequestControlThread() #更新请求处理method相关数据内容 temp_set_data_suc_flag=DispathMethodRequest.set_method_request_control_thread_management_property_data(thread_node,in_method_data) if not temp_set_data_suc_flag: del thread_node return #启动线程,开始处理数据 thread_node.start() #保存有效线程对象句柄到处理线程对象句柄列表 client_request_control_thread_object_list.append(thread_node) else: idle_thread_node_handle=DispathMethodRequest.get_idle_method_request_control_thread_handle() if not idle_thread_node_handle: log.debug_info("New Method Request Control Thread and start run thread") #创建新的处理线程,并将消息分发到该线程 thread_node=_MethodRequestControlThread() #更新请求处理method相关数据内容 temp_set_data_suc_flag=DispathMethodRequest.set_method_request_control_thread_management_property_data(thread_node,in_method_data) if not temp_set_data_suc_flag: del thread_node return #启动线程,开始处理数据 thread_node.start() #保存有效线程对象句柄到处理线程对象句柄列表 client_request_control_thread_object_list.append(thread_node) else: log.debug_info("Push Method Request data to idle thread control module") #将消息分发到刚获取的空闲处理线程 idle_thread_node_handle.push_request_method_data_to_property(in_method_data) except Exception, e: err_info = "Dispath method request to control thread occurs expection: %s" % e log.debug_err(err_info) #返回错误消息 in_conn_handle=in_method_data.get_client_conn_handle() ClientResponseHandle.send_error_info_data_to_client(in_conn_handle,err_info)