class WebSocketThread(Thread): """Websocket thread.""" def __init__(self, url, client, on_startup=None): super().__init__() self.ws = WebSocket(url) self._client = weakref.ref(client) self.on_startup = on_startup or (lambda: None) self.running = False self.ready_event = Event() self.error = None self.daemon = True @property def client(self): return self._client() def run(self): """Main thread loop.""" try: with self.ws: for event in self.ws: if event.name == 'rejected': self.error = event.reason elif event.name == 'disconnected': if not event.graceful: self.error = event.reason elif event.name == 'ready': self.running = True self.on_startup() self.ready_event.set() elif event.name == 'binary': self.on_binary(event.data) except Exception: log.exception('error in m2m thread') finally: self.running = False self.ready_event.set() def on_binary(self, data): """Called with a binary message.""" if not self.client: log.warning('ws message %r ignored', data) return try: packet = M2MPacket.from_bytes(data) except PacketFormatError as packet_error: # We received a badly formatted packet from the server # Inconceivable! log.warning('bad packet (%s)', packet_error) else: log.debug(' <- %r', packet) self.client.dispatcher.dispatch_packet(packet) def send(self, data): """Send binary message (low level interface).""" self.ws.send_binary(data) def close(self): """Close the websocket.""" self.ws.close()
async def websocket_handler(uri, headers): websocket = WebSocket(uri) for header, value in headers.items(): websocket.add_header(str.encode(header), str.encode(value)) for msg in websocket.connect(ping_rate=5): if msg.name == "text": message = msg.text message = re.sub(r"[\x00-\x1f\x7f-\x9f]", "", message) message_data = json.loads(message) logging.info(str(message_data).encode("utf-8")) if "error" in message_data and message_data["error"] == "Auth not valid": logging.info(message_data) raise RuntimeError("Connection settings invalid") elif message_data["type"] != "interaction": logging.info(message_data) if message_data["type"] == "question": question_str = unidecode(message_data["question"]) answers = [unidecode(ans["text"]) for ans in message_data["answers"]] print("\n" * 5) print("Question detected.") print(f"Question {message_data['questionNumber']} out of {message_data['questionCount']}") print(f"{Fore.CYAN}{question_str}\n{answers}{Style.RESET_ALL}") print() await question.answer_question(question_str, answers, message_data['questionNumber'],{message_data['questionCount']}) print("Socket closed")
def __init__(self, manager, url, uuid=None, channel_callback=None, control_callback=None, **kwargs): super(WSClient, self).__init__() self.manager = manager self.url = url _user_agent = "Agent/{} {}".format(__version__, LOMOND_USER_AGENT) self.websocket = WebSocket(url, agent=_user_agent) self.channel_callback = channel_callback self.control_callback = control_callback self._closed = False self.identity = uuid self.channels = {} self.last_packet_time = time.time() self.callback_lock = threading.RLock() self.write_lock = threading.Lock() self.callbacks = defaultdict(list) self.hooks = defaultdict(list) self.dispatcher = Dispatcher(packet_cls=Packet, handler_instance=self, log=log) self.name = "m2m" # Thread name self.daemon = True
class WsClient(threading.Thread): """ Web Socket Client Establishes a persistent WSS client that launches a separate thread to handle WSS operations. Spools incoming messages to the q_rx Queue, and sends any messages placed into the q_tx Queue. """ def __init__(self, cfg, q): """ Class Initializer :param cfg: {dict} Emulator's configuration dictionary :param q: {Queue} WSS RX/TX Message Queue """ self.q_rx = q['rx'] self.q_tx = q['tx'] self.stop = False self.ready = False self.ws = WebSocket(url=cfg['SERVICE.STATUS_SERVICE_URL'] + '/' + cfg['SESSION.WS_TOKEN'], protocols=['glowforge'], agent=cfg['SESSION.USER_AGENT']) self.ignore_events = [ 'ping', 'pong', 'poll', 'connecting', 'connected' ] threading.Thread.__init__(self) def run(self): """ Thread loop Listens for WS messages, and adds them the q_rx Queue. Monitors the q_tx, and sends any messages it finds. Handles PING, PONG, and POLL messages. :return: """ for event in persist(self.ws): logging.info('RX-EVENT: ' + event.name) logging.debug(event) if self.stop: logging.info('STOP REQUESTED') break # WS reporting session is established if event.name == 'ready': self.ready = True # Service has sent us a text message elif event.name == 'text': logging.debug(event.text) self.q_rx.put(event.text) elif event.name not in self.ignore_events: logging.error('UNKNOWN RX-EVENT: ' + event.name) while self.ready: if not self.q_tx.empty(): send_msg = self.q_tx.get() logging.info('TX-EVENT: ' + send_msg) self.ws.send_text(send_msg) self.q_tx.task_done() else: break logging.info('CLOSING') self.ws.close()
def __init__(self, url, client, on_startup=None): super().__init__() self.ws = WebSocket(url) self._client = weakref.ref(client) self.on_startup = on_startup or (lambda: None) self.running = False self.ready_event = Event() self.error = None self.daemon = True
async def websocket_lives_handler(uri, bearers, broadid): for bearer in bearers: headers = { "Authorization": "Bearer %s" % bearer, "x-hq-client": "Android/1.3.0" } websocket = WebSocket(uri) for header, value in headers.items(): websocket.add_header(str.encode(header), str.encode(value)) first = True for msg in websocket.connect(ping_rate=5): if msg.name == "text": message = msg.text message = re.sub(r"[\x00-\x1f\x7f-\x9f]", "", message) message_data = json.loads(message) if "error" in message_data and message_data[ "error"] == "Auth not valid": print("Connection settings invalid") if first == True: websocket.send_json({ "authToken": bearer, "type": "subscribe", "broadcastId": broadid }) first = False else: websocket.close()
def mainloop(self): input("<press enter>") print(TO_STOP_PRESS) srv = random.choice(self.SERVERS) logger.debug(srv) conn = WebSocket(srv) corrects = 0 last_answer = None for msg in conn.connect(): if msg.name == "text": a = json.loads(msg.text) if a["method"] == "round_question": b = a["params"]["answers"] googler = KleverGoogler(a["params"]["text"], [b[i]["text"] for i in range(4)], int(time.time()), a["params"]["number"]) googler.search() c = googler.genQuestion() last_answer = int(c.best[0]) message = QUESTION % (str(c.id), c.question) message += "\n==============================\n" for i in range(4): message += ("[~]" if i + 1 == last_answer else "[ ]") + "Answer " + str(i + 1) + ":" + str(c.answers[i]) message += "\n\n==============================\n" print(message) if config["Config"]["debug_mode"] in ("basic", "verbose"): logger.info("Query for custom question:\n" + str(c)) logger.info("Optimized question:" + c.optimized) if config["Config"]["answer_ui"] == "on" and config["Social"]["telegram_auto"] == "on" \ or config["Social"]["telegram"] == "on": send_to_telegram(message) elif a["method"] == "round_result": b = a["params"] c = a["params"]["answers"] message = ANSWER_FOR_QUESTION % (b["number"], b["text"]) message += "\n==============================\n" correct = -1 for q in c: d = False if q["correct"]: d = True correct = q["number"] message += ("[x]" if d else "[ ]") + ANSWER + " %s: %s" % (q["number"], q["text"]) + "\n" message += "\n==============================" if last_answer == correct: corrects += 1 message += BOT_STATUS + (CORRECT if last_answer == correct else INCORRECT) + ", " + \ str(corrects) + "/" + str(b["number"]) elif msg.name == "disconnected": print("disconnected")
def copy_to_websocket( ws: lomond.WebSocket, f: io.RawIOBase, ready_sem: threading.Semaphore ) -> None: ready_sem.acquire() try: while True: chunk = f.read(4096) if not chunk: break ws.send_binary(chunk) finally: f.close() ws.close()
def test_broken(self): """Test server that closes gracefully.""" ws = WebSocket(self.WS_URL + 'broken') events = list(ws.connect(ping_rate=0)) assert len(events) == 7 assert events[0].name == 'connecting' assert events[1].name == 'connected' assert events[2].name == 'ready' assert events[3].name == 'poll' assert events[4].name == 'text' assert events[4].text == u'foo' assert events[5].name == 'protocol_error' assert not events[5].critical assert events[6].name == 'disconnected' assert not events[6].graceful
def copy_from_websocket( f: io.RawIOBase, ws: lomond.WebSocket, ready_sem: threading.Semaphore, cert_file: Optional[str], cert_name: Optional[str], ) -> None: try: for event in ws.connect( ping_rate=0, session_class=lambda socket: CustomSSLWebsocketSession(socket, cert_file, cert_name), ): if isinstance(event, lomond.events.Binary): f.write(event.data) elif isinstance(event, lomond.events.Ready): ready_sem.release() elif isinstance( event, (lomond.events.ConnectFail, lomond.events.Rejected, lomond.events.ProtocolError), ): raise Exception("Connection failed: {}".format(event)) elif isinstance(event, (lomond.events.Closing, lomond.events.Disconnected)): break finally: f.close()
def update_report(): """Tell wstest to update reports.""" print("Updating reports...") qs = urlencode({'agent': USER_AGENT}) url = server + "/updateReports?{}".format(qs) for _ in WebSocket(url): pass
def runWebsocketThread(self): attempt = 0 while self.running: if attempt > 0: time.sleep(0.25) attempt = attempt + 1 self.websocket = WebSocket(self.uri) for event in self.websocket: if event.name == 'text': packetObj = None try: packetObj = json.loads(event.text) except: print("Failed parsing a Websocket event as JSON: " + event.text) continue if packetObj == None: print("Got a NULL event for some reason.") continue self.packetsLock.acquire() self.packets.append(packetObj) self.packetsLock.release() else: if not self.running: print("Websocket client thread exiting.") return
def test_non_graceful(self): """Test server that closes socket.""" ws = WebSocket(self.WS_URL + 'non-graceful') events = list(ws.connect(ping_rate=0)) assert len(events) == 7 assert events[0].name == 'connecting' assert events[1].name == 'connected' assert events[2].name == 'ready' assert events[3].name == 'poll' assert events[4].name == 'text' assert events[4].text == u'foo' assert events[5].name == 'binary' assert events[5].data == b'bar' assert events[6].name == 'disconnected' assert not events[6].graceful
def test_bad_proxy(): proc = subprocess.Popen(['proxy.py', '--port', '8888']) try: time.sleep(0.1) ws = WebSocket('wss://echo.websocket.org', proxies={'https': 'http://bad.test:8888'}) events = [] for event in ws: events.append(event) if event.name == 'ready': ws.close() assert len(events) == 2 assert events[0].name == 'connecting' assert events[1].name == 'connect_fail' finally: os.kill(proc.pid, 3)
def test_echo_no_pong(self): """Test echo server.""" # No way to disable pongs from tornado, so we will set the # ping timeout to so low it couldn't get the pong in time ws = WebSocket(self.WS_URL + 'echo') events = [] for event in ws.connect(poll=60, ping_rate=1, auto_pong=False, ping_timeout=0.000001): events.append(event) assert len(events) == 6 assert events[0].name == 'connecting' assert events[1].name == 'connected' assert events[2].name == 'ready' assert events[3].name == 'poll' assert events[4].name == 'unresponsive' assert events[5].name == 'disconnected' assert not events[5].graceful
def connect_websocket(socket_url, auth_token): headers = { "Authorization": f"Bearer {auth_token}", "x-hq-client": "iPhone8,2" } websocket = WebSocket(socket_url) for header, value in headers.items(): websocket.add_header(str.encode(header), str.encode(value)) for msg in websocket.connect(ping_rate=5): if msg.name == "text": message = msg.text message = re.sub(r"[\x00-\x1f\x7f-\x9f]", "", message) message_data = json.loads(message) if message_data['type'] == 'question': question = message_data['question'] qcnt = message_data['questionNumber'] Fullcnt = message_data['questionCount'] print(f"\nQuestion number {qcnt} out of {Fullcnt}\n{question}") #open_browser(question) answers = [ unidecode(ans["text"]) for ans in message_data["answers"] ] print(f"\n{answers[0]}\n{answers[1]}\n{answers[2]}\n") Google_Search.answer_question(question, answers) elif message_data["type"] == "questionSummary": answer_counts = {} correct = "" for answer in message_data["answerCounts"]: ans_str = unidecode(answer["answer"]) if answer["correct"]: correct = ans_str advancing = message_data['advancingPlayersCount'] eliminated = message_data['eliminatedPlayersCount'] print(colored(correct, "blue")) print(advancing) print(eliminated)
def __init__(self, cfg, q): """ Class Initializer :param cfg: {dict} Emulator's configuration dictionary :param q: {Queue} WSS RX/TX Message Queue """ self.q_rx = q['rx'] self.q_tx = q['tx'] self.stop = False self.ready = False self.ws = WebSocket(url=cfg['SERVICE.STATUS_SERVICE_URL'] + '/' + cfg['SESSION.WS_TOKEN'], protocols=['glowforge'], agent=cfg['SESSION.USER_AGENT']) self.ignore_events = [ 'ping', 'pong', 'poll', 'connecting', 'connected' ] threading.Thread.__init__(self)
def __init__(self, api: HQApi): self.api = api self.authtoken = HQApi.api(api).authtoken self.region = HQApi.api(api).region self.headers = { "x-hq-stk": base64.b64encode(str(self.region).encode()).decode(), "x-hq-client": "Android/1.20.1", "Authorization": "Bearer " + self.authtoken} if HQApi.get_show(api)["active"]: self.socket = HQApi.get_show(api)["broadcast"]["socketUrl"].replace("https", "wss") self.broadcast = HQApi.get_show(api)['broadcast']['broadcastId'] else: print("Using demo websocket!") self.socket = "ws://hqecho.herokuapp.com" # Websocket with questions 24/7 self.broadcast = 1 self.ws = WebSocket(self.socket) for header, value in self.headers.items(): self.ws.add_header(str.encode(header), str.encode(value)) for _ in self.ws.connect(): self.success = 1
def get_test_count(): """Gets the number of test cases.""" ws = WebSocket(server + '/getCaseCount') case_count = None for event in ws: if event.name == 'text': case_count = json.loads(event.text) if case_count is None: print('Could not get case count. Is the test server running?') sys.exit(-1) return case_count
def connect_websocket(socket_url, auth_token): headers = {"Authorization": f"Bearer {auth_token}", "x-hq-client": "Android/1.3.0"} websocket = WebSocket(socket_url) for header, value in headers.items(): websocket.add_header(str.encode(header), str.encode(value)) for msg in websocket.connect(ping_rate=5): if msg.name == "text": message = msg.text message = re.sub(r"[\x00-\x1f\x7f-\x9f]", "", message) message_data = json.loads(message) if message_data['type'] == 'question': question = message_data['question'] cnt = message_data['questionCount'] print('{}. {}'.format(cnt, question)) open_browser(question)
def __init__(self, q_rx: Queue, q_tx: Queue): """ Class Initializer :param q_rx: WSS RX Message Queue :type q_rx: Queue :param q_tx: WSS TX Message Queue :type q_tx: Queue """ self.msg_q_rx = q_rx self.msg_q_tx = q_tx self.stop = False self.ready = False self.ws = WebSocket(url=get_cfg('SERVICE.STATUS_SERVICE_URL') + '/' + get_cfg('SESSION.WS_TOKEN'), protocols=['glowforge'], agent=get_cfg('SESSION.USER_AGENT')) self.ignore_events = [ 'ping', 'pong', 'poll', 'connecting', 'connected' ] Thread.__init__(self)
def __init__(self, api: HQApi, demo: bool = False, proxy: str = None): self.api = api self.handlers = {} self.authtoken = self.api.authtoken self.headers = self.api.headers self.use_demo = False try: self.headers["Authorization"] except: if demo: self.use_demo = True else: raise WebSocketNotAvailable( "You can't use websocket without bearer") try: self.show = HQApi.get_show(api) self.socket = self.show["broadcast"]["socketUrl"].replace( "https", "wss") self.broadcast = self.show['broadcast']['broadcastId'] except BannedIPError or ApiResponseError: if demo: self.use_demo = True else: raise WebSocketNotAvailable( "You can't use websocket with banned IP or invalid auth") except: if demo: self.use_demo = True else: raise NotLive("Show isn't live and demo mode is disabled") if self.use_demo: print( "[HQApi] Using demo websocket! Don't create issues with this websocket" ) self.socket = "wss://hqecho.herokuapp.com" # Websocket with questions 24/7 self.broadcast = 1 self.ws = WebSocket(self.socket) else: self.ws = WebSocket(self.socket) for header, value in self.headers.items(): self.ws.add_header(str.encode(header), str.encode(value))
def main(): websocket = WebSocket(ARGS.server) # TODO: compress? print_output("Connecting to '%s'..." % websocket.url) vad_audio = VADAudio(aggressiveness=ARGS.aggressiveness) print_output("Listening (ctrl-C to exit)...") audio_consumer_thread = threading.Thread( target=lambda: audio_consumer(vad_audio, websocket)) audio_consumer_thread.start() websocket_runner(websocket)
async def websocket_handler(uri, headers): websocket = WebSocket(uri) for header, value in headers.items(): websocket.add_header(str.encode(header), str.encode(value)) for msg in websocket.connect(ping_rate=5): if msg.name == "text": message = msg.text message = re.sub(r"[\x00-\x1f\x7f-\x9f]", "", message) message_data = json.loads(message) if "error" in message_data and message_data[ "error"] == "Auth not valid": raise RuntimeError("Connection settings invalid") elif message_data["type"] != "interaction": if message_data["type"] == "question": question_str = unidecode(message_data["question"]) answers = [ unidecode(ans["text"]) for ans in message_data["answers"] ] print("\n" * 5) print("Question detected.") print("Question %s out of %s" % (message_data['questionNumber'], message_data['questionCount'])) with open("uk.txt", "w") as uk: uk.write("\nQuestion %s out of %s" % (message_data['questionNumber'], message_data['questionCount'])) aMsg = Fore.CYAN + question_str + "\n" for a in answers: aMsg = aMsg + "\n" + a aMsg = aMsg + Style.RESET_ALL print() await question.answer_question(question_str, answers) print("Socket closed")
def test_proxy(): proc = subprocess.Popen(['proxy.py', '--port', '8888']) try: time.sleep(1) ws = WebSocket('wss://echo.websocket.org', proxies={'https': 'http://127.0.0.1:8888'}) events = [] for event in ws: events.append(event) if event.name == 'ready': ws.close() assert len(events) == 6 assert events[0].name == 'connecting' assert events[1].name == 'connected' assert events[1].proxy == 'http://127.0.0.1:8888' assert events[2].name == 'ready' assert events[3].name == 'poll' assert events[4].name == 'closed' assert events[5].name == 'disconnected' finally: os.kill(proc.pid, 3)
def __init(self, cookie): self.websocket = WebSocket(self.websocket_uri) self.websocket.add_header("Cookie".encode("utf-8"), cookie.encode("utf-8")) self.socket_ready = threading.Event() self.event_ready = threading.Event() self.stopper = threading.Event() t = threading.Thread(name="iris_listener", target=self.__socket_run) r = threading.Timer(1.0, self.__refresh_database) self.workers = [t, r] #handler = SignalHandler(self.stopper, self.workers) #signal.signal(signal.SIGINT, handler) for i, worker in enumerate(self.workers): print('Starting worker {}'.format(i)) worker.start() if self.socket_ready.wait(5): session = Session(self) session.SetActivePlace(placeId=self.place_id) if session.success: self.account = Account(self) self.place = Place(self) self.rule = Rule(self) self.scene = Scene(self) db.prepare_database() self.__configure_database() self.place.GetHub() if self.place.success: self.hub_address = self.place.response["payload"][ "attributes"]["hub"]["base:address"] self.time_ready = utils.now() else: # use an exception print("failed to get the hub's address") self.stop()
def run_ws(url): """Run a websocket until close.""" ws = WebSocket(url, compress=True) for event in ws.connect(ping_rate=0): try: if event.name == 'text': ws.send_text(event.text, compress=True) elif event.name == 'binary': ws.send_binary(event.data, compress=True) except Exception: log.exception('error running websocket') break
def start_websocket(self): self.websocket = WebSocket(f'ws://{self.address}/') for event in persist(self.websocket): if event.name == 'ready': self.websocket.send_json(command='join_group', data=dict(key=self.key)) if event.name == 'text': if event.json['command'] == 'new_id': self.websocket_id = event.json['id'] if event.json['command'] == 'new_view': print('New view') print(event.json['source']) print(self.websocket_id) if event.json['source'] != self.websocket_id: flare.invoke_later(target=self.set_camera, args=(event.json['view'], )) if self.thread_exit: self.thread_exit = False break
def websocket_task(self) -> None: """ Runs the websocket task. """ ws = WebSocket(self.url, agent=USER_AGENT) self._ws = ws # generate poll events every 0.5 seconds to see if we can cancel websocket = persist(ws, ping_rate=0, poll=1, exit_event=self._cancelled) for event in websocket: self._portal.run(self._queue.put, event) # signal the end of the queue self._portal.run(self._queue.put, self._done)
def run_ws(url): """Run a websocket until close.""" ws = WebSocket(url) for event in ws: try: if event.name == 'text': ws.send_text(event.text) elif event.name == 'binary': ws.send_binary(event.data) except: log.exception('error running websocket') break