def __init__(self, port, type, params={}): super(QkConnect, self).__init__(type, params) self._hostname = "localhost" self._port = port self._json_parser = JsonParser() self._json_parser.set_callback("parsed", self._handle_json) self._client = None self._thread_listener = None self._alive = False self._event = threading.Event() self._process = None self._process_thread = None self._event.clear()
class QkConnect(Conn): _nextID = 0 _next_port = 1238 def __init__(self, port, type, params={}): super(QkConnect, self).__init__(type, params) self._hostname = "localhost" self._port = port self._json_parser = JsonParser() self._json_parser.set_callback("parsed", self._handle_json) self._client = None self._thread_listener = None self._alive = False self._event = threading.Event() self._process = None self._process_thread = None self._event.clear() def __del__(self): print "Deleting QkConnect %d" % self._id def __repr__(self): id_hex = hex(self._id)[2:0].zfill(4) return "%s %s %s" % (id_hex, self._type, self._params) def run(self): self._event.clear() qkconnect_exe = path.normpath(QKCONNECT_EXE) cmd = [qkconnect_exe, self._hostname, "%d" % self._port, self._type, "--verbose"] self.log.debug("%s CMD: %s" % (self.__class__.__name__, cmd)) self._process = subprocess.Popen( cmd, stdin=_DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=1 ) self._process_thread = threading.Thread(target=self._process_listener, args=[self._process.stdout]) self._process_thread.setDaemon(True) self._process_thread.start() if self._event.wait(3.0) is False: self._error("Failed to create QkConnect") return False QkConnect._nextID += 1 self._connect() self._set_state(Conn.StateRunning) return True def _connect(self): self._client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self._client.connect((self._hostname, self._port)) self._thread_listener = threading.Thread(target=self._listener) self._thread_listener.setDaemon(True) self._alive = True self._thread_listener.start() def stop(self): self._alive = False self._client.close() self._thread_listener.join() self._process.terminate() self._set_state(Conn.StateStopped) def _handle_json(self, json_str): json_data = json.loads(json_str) json_keys = json_data.keys() #TODO add timestamps to packets if "pkt" in json_keys: json_data.update({ "conn": { "id": self._id } }) if self._callbacks["packet_received"] is not None: self._callbacks["packet_received"](json_data) else: self._error("Unknown JSON format: %s" % json_str) def _process_listener(self, stdout): while self._process.poll() is None: for line in iter(stdout.readline, b""): nline = line.rstrip("\r\n") if "ready" in nline: self.log.debug("QkConnect is READY") self._event.set() self.log.debug("STDOUT %s %s: %s" % (self, self._port, nline)) def _listener(self): while self._alive: input,output,err = select.select([self._client], [], []) for rd in input: if self._alive is True: data = rd.recv(256) self._json_parser.parse_data(data) def send_packet(self, pkt): pkt_json_str = json.dumps(pkt) self._client.send(pkt_json_str)