class GameSocket: def __init__(self, cookie): self.game_socket = None self.cookie = cookie pass @staticmethod def on_open(ws): def run(*args): while (True): pass thread.start_new_thread(run, ()) def open_game(self): def on_recive(ws, message): message = json.loads(message) self.handle(message) pass self.game_socket = WebSocketApp("ws://localhost:8080/game", cookie=self.cookie, on_message=on_recive) self.game_socket.on_open = self.on_open self.game_socket.run_forever() def handle(self, message): print(message) tp = message["type"] if tp == "GetCardFromHand": self.game_socket.send( '{"type":"ChooseCardFromHand", "chosenCard":0}') if tp == "GetCardFromTable": self.game_socket.send( '{"type":"ChooseCardFromTable", "chosenCard":0}')
def _run_websocket(self, ws: WebSocketApp): try: ws.run_forever() except Exception as e: raise Exception(f'Unexpected error while running websocket: {e}') finally: self._reconnect(ws)
class LobbySocket: def __init__(self, cookie): self.lobby_socket = None self.cookie = cookie pass @staticmethod def on_open(ws): def run(*args): while (True): pass thread.start_new_thread(run, ()) def open_lobby(self): def on_recive(ws, message): message = json.loads(message) self.handle(message) pass self.lobby_socket = WebSocketApp("ws://localhost:8080/lobby", cookie=self.cookie, on_message=on_recive) self.lobby_socket.on_open = self.on_open self.lobby_socket.run_forever() def handle(self, message): print(message) pass
def run(self): """ Run the bot with a live game websocket """ if not self.config.has_section('Auth'): exit('Error: Config file \'config.ini\' with [Auth] section not found. Please run generate-token.') while True: self.current_game = '' self.broadcast_ended = False socket_url = self.get_socket_url(self.headers) if socket_url: print('CONNECTING TO UK SHOW: %s' % socket_url) web_socket = WebSocketApp(socket_url, on_open=lambda _ws: print('CONNECTION SUCCESSFUL'), on_message=self.on_message, on_error=lambda _ws, err: print('ERROR: %s' % err), on_close=lambda _ws: print('SOCKET CLOSED'), header=self.headers) while not self.broadcast_ended: try: web_socket.run_forever(ping_interval=5) except (WebSocketException, WebSocketTimeoutException): print('CONNECTION LOST. RECONNECTING...') elif self.next_show_time: next_show_time = parser.parse(self.next_show_time) seconds_until_show = (next_show_time - datetime.now(utc)).total_seconds() if seconds_until_show < 0: print('\nGame should have started. Sleeping for 10 seconds.') sleep(10) else: print('\nSleeping until {} ({} seconds)'.format(next_show_time.strftime('%c'), seconds_until_show)) sleep(seconds_until_show) else: print(f'Could not connect to API at {self.api_url}. Sleeping for 10 seconds.') sleep(10)
def watchover(): os.chdir(os.getcwd()) cmd = "export SUDO_ASKPASS=./pwd.sh && sudo -A ./activate.sh" p = Popen(cmd, shell=True) # p.wait(60) time.sleep(17) while 1: logger.info("start connection") while 1: # 保证socket持续运行 before = time.time() ws = WebSocketApp(SKT_ADDR) ws.run_forever() end = time.time() if end - before < 2: break logger.info("portia disconnected") print("portia disconnected") p.kill() os.popen( "export SUDO_ASKPASS=./pwd.sh && sudo -A docker stop $(sudo -A docker ps)" ) time.sleep(10) p = Popen(cmd, shell=True) # p.wait(60) time.sleep(17)
def main(): ##Main function while (True): try: URL = 'wss://ws-feed.gdax.com' ws = WebSocketApp(URL, on_open=on_open, on_close=on_close, on_error=on_error, on_message=on_message) ws.run_forever() except WebSocketConnectionClosedException as e: print( "WebSocketConnectionClosedException:Failed to recreate connection to host, please ensure network connection to host: {}" .format(URL)) print(e) print(os.sys.exc_info()[0:2]) except WebSocketTimeoutException as e: print( "WebSocketTimeoutException: Failed to recreate connection to hos, please ensure network connection to host: {}" .format(URL)) print(e) print(os.sys.exc_info()[0:2]) except Exception as e: print( "Exception: Failed to (re-)create connection to host, please ensure network connection to host: {}" .format(URL)) print(e) print(os.sys.exc_info()[0:2])
def on_connect(): #enableTrace(True) ws = WebSocketApp(SERVER_REMOTE_ADDRESS, on_message=on_message, on_error=on_error, on_close=on_close, on_open=on_open) ws.run_forever()
def _run_websocket(self, ws: WebSocketApp) -> None: try: ws.on_open = self._wrap_callback(self._on_ws_open_callback) ws.run_forever(origin=self.ws_origin) except Exception as e: raise Exception(f'Unexpected error while running websocket: {e}') finally: self._reconnect(ws)
def main(): """Main function.""" ws = WebSocketApp(URL, on_open=on_open, on_message=on_message) ws.run_forever(sslopt={ "cert_reqs": ssl.CERT_NONE, "check_hostname": False }) print
def connect_websocket(): ws = WebSocketApp("wss://api.upbit.com/websocket/v1", on_message=on_message, on_error=on_error, on_close=on_close, on_open=on_open) start = time.time() ws.run_forever()
class SessionWebSocket(Thread): sessions = {} def __init__(self, name, url): super(SessionWebSocket, self).__init__() if SessionWebSocket.sessions.get(url): raise DuplicatedSessionError("A session with " "this urls is already created!") SessionWebSocket.sessions[url] = self self.name = name self.url = url self.ws = None self.ignore_next_update = False def set_ws(self): self.ws = WebSocketApp(self.url, on_message=self.on_message, on_error=self.on_error) def run(self): while True: self.set_ws() self.ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE}) @classmethod def get_sws(cls, url): sws: SessionWebSocket = SessionWebSocket.sessions.get(url) if sws is None: raise SessionWebSocketNotFoundError(f'A SWS with the url {url} ' f'was not found!') return sws @staticmethod def on_message(ws: WebSocketApp, msg): sws: SessionWebSocket = SessionWebSocket.get_sws(ws.url) if not sws.ignore_next_update: msg = UpdateMessage.from_msg(sws.name, msg) logger.info(f'SessionUpdateMessage received from {msg.sws_name}') JackBot.instance().send_message(f'{msg}', parse_mode='HTML') else: sws.ignore_next_update = False @staticmethod def on_error(ws, error: Exception): sws: SessionWebSocket = SessionWebSocket.get_sws(ws.url) sws.ignore_next_update = True logger.warning(error) @classmethod def start_all(cls): for session in cls.sessions.values(): session.start() @classmethod def join_all(cls): for session in cls.sessions.values(): session.join()
def main(): sleep(0.5) url = 'ws://127.0.0.1:8181/core' print('Starting client on:', url) client = WebSocketApp(url=url, on_message=on_message) if mock: Thread(target=run_wifi_setup, args=[client, {}], daemon=True).start() client.run_forever() print('Client stopped.')
class GameSocket: def __init__(self, cookie, testsystem): self.game_socket = None self.cookie = cookie self.testsystem = testsystem self.errorst = False self.error_next = False self.good_msg = '' pass @staticmethod def on_open(ws): def run(*args): while(True): pass thread.start_new_thread(run, ()) def open_game(self): def on_recive(ws,message): message = json.loads(message) self.handle(message) pass self.game_socket = WebSocketApp("ws://localhost:8080/game",cookie=self.cookie, on_message=on_recive) self.game_socket.on_open = self.on_open self.game_socket.run_forever() def truehandl(self,message): tp = message["type"] if tp == "ErrorMsg": #print("error handled") self.game_socket.send(self.good_msg) self.error_next = False self.errorst = False if self.error_next: self.testsystem.fail("error was not") def fakehandl(self,message): tp = message["type"] if tp == "GetCardFromHand": self.game_socket.send('#####ERROR#####') self.good_msg = '{"type":"ChooseCardFromHand", "chosenCard":0}' #print("error send") self.errorst = True self.error_next = True if tp == "GetCardFromTable": self.game_socket.send('#####ERROR#####') self.good_msg = '{"type":"ChooseCardFromTable", "chosenCard":0}' #print("error send") self.errorst = True self.error_next = True def handle(self,message): #print(message) #print(self.errorst) if self.errorst: self.truehandl(message) else: self.fakehandl(message)
def run(ws: websocket.WebSocketApp): """Starts the websocket loop""" ws.run_forever( sslopt={ "cert_reqs": ssl.CERT_NONE, "check_hostname": False }, ping_interval=10, )
class WebsocketClient: ''' Websocket Client ラッパークラス ''' def __init__(self): self.client = None self.logger = create_logger() def open(self, server_host): ''' server_hostにクライアントを新規接続 ''' self.close() self.client = create_connection(server_host) def open_server(self, server_host): ''' server_hostにクライアントを新規接続し、サーバーとして動作させる ''' self.close() enableTrace(False) self.client = WebSocketApp( server_host, on_message=lambda ws, message: self.on_message_recieved(message), on_error=lambda ws, error: self.on_error(error), on_close=lambda ws: self.on_disconnect()) self.client.on_open = lambda ws: self.on_connect() self.client.run_forever() def close(self): ''' clientをサーバーから切断する ''' if self.client is not None: self.client.close() self.client = None def log(self, msg, *args, **kargs): ''' ログメッセージを出力 ''' self.logger.info(msg, *args, **kargs) def send_message(self, message): ''' 接続先のサーバーにmessage送信 ''' return self.client.send(message) def recieve_message(self): ''' 接続先サーバーから送られてきたメッセージを受信 ''' return self.client.recv() # --- event methods (サーバーモードで動作する際に使用) --- # def on_connect(self): ''' Websocketサーバー接続時のコールバック ''' self.log('Connect') def on_disconnect(self): ''' Websocketサーバーから切断時のコールバック ''' self.log('Disconnect') def on_message_recieved(self, message): ''' Websocketサーバーからメッセージ受信時のコールバック ''' self.log('Received:{}'.format(message)) def on_error(self, error): ''' エラー発生時のコールバック ''' self.log('Error:{}'.format(error))
def crawl_start(self, url, ws_headers): enableTrace(False) # 参数是True时,会显示发送的msg ws = WebSocketApp(url=url, on_message=self.on_message, on_error=self.on_error, on_close=self.on_close, header=ws_headers) ws.on_open = self.on_open ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE}) # 忽略认证
class GDAXWebsocket: """ Stream product data Store in memory until time frame met then write to DB """ def __init__(self): self.__ws = None @staticmethod def __handle_error(ws, error): print(f'WS Error: {error}') def __open_websocket(self, subscribe_data: dict, process_data_func: Callable): """ :param subscribe_data: Channel subscribe data :param process_data_func: function that takes two arguments (ws, message) :return: """ def __on_open(ws): ws.send(data=json.dumps(subscribe_data)) self.__ws = WebSocketApp(WEBSOCKET_URL, on_message=process_data_func, on_error=self.__handle_error) self.__ws.on_open = __on_open self.__ws.run_forever() def close_websocket(self): self.__ws.close() def ticker_channel_socket(self, process_data_func: Callable, product_ids = List[str]): """ Example Response [{ "type": "ticker", "trade_id": 20153558, "sequence": 3262786978, "time": "2017-09-02T17:05:49.250000Z", "product_id": "BTC-USD", "price": "4388.01000000", "side": "buy", // Taker side "last_size": "0.03000000", "best_bid": "4388", "best_ask": "4388.01" },] :param process_data_func: function to process data on socket receive :param product_ids: List of string product ids: ['ETH-USD', 'ETH-BTC'] :return: """ print('Creating Socket') subscribe_data = { 'type': 'subscribe', 'product_ids': product_ids, 'channels': [{'name': 'ticker', 'product_ids': product_ids}] } self.__open_websocket(subscribe_data, process_data_func=process_data_func) return self.__ws
def run_forever(self, sockopt=None, sslopt=None, ping_interval=0, ping_timeout=None): WebSocketApp.run_forever(self, sockopt=sockopt, sslopt=sslopt, ping_interval=ping_interval, ping_timeout=ping_timeout)
class RaspberryPiSignal: __wsUrl = "ws://raspberrypi:9453" __ws = None __task = None __alertTagCollection = None def __init__(self, alertTagCollection): # enableTrace(True) # 啟動偵錯模式 self.__alertTagCollection = alertTagCollection self.__createTask() # 將接收websocket訊號的方法,使用執行序背景執行 def __createTask(self): if self.__task is None: self.__task = threading.Thread(target=self.__createWebsocket) self.__task.setDaemon(True) # 設定保護執行序,會隨著主視窗關閉,執行序會跟著kill self.__task.start() # 關閉執行序 def closeTask(self): self.__ws.close() self.__ws = None self.__task = None self.__alertTagCollection = None # 產生WebSocket連線 def __createWebsocket(self): if self.__ws is not None: return self.__ws = WebSocketApp(self.__wsUrl, on_open=self.__onOpen, on_message=self.__onMessage, on_error=self.__onError, on_close=self.__onClose) self.__ws.run_forever() def __onMessage(self, message): if self.__alertTagCollection is None: return # 根據收到的Websocket哪一個Alert設備,去執行這一個AlertTag觸發警報事件 self.__alertTagCollection[int(message)].TriggerAlert() print("收到的Alert Tag號碼" + message) def __onError(self, error): print("###WebSocket-Error###") print(error) self.closeTask() def __onClose(self): print("###WebSocket-Close###") self.closeTask() def __onOpen(self): print("###WebSocket-Open###")
class ModelStateAdapter(Thread): msg_size_len = 10 msg_size_fmt = '{:0%d}' % msg_size_len def __init__(self, key, port): super(ModelStateAdapter, self).__init__() self.daemon = True self.key = key self.port = port self.read_fd, self.write_fd = os.pipe() def _send(self, msg): os.write(self.write_fd, self.msg_size_fmt.format(len(msg))) os.write(self.write_fd, msg) def stop(self): self.socket.close() def recv(self): msg_size = int(os.read(self.read_fd, self.msg_size_len)) return loads(os.read(self.read_fd, msg_size)) def authenticate(self, key, nonce): logging.debug('authenticating...') mac = hmac.new(str(key), str(nonce)).digest().encode('hex') self.socket.send(dumps({ 'msg': 'auth_response', 'mac': mac, })) def request_state(self, active_tag): logging.debug('requesting state...') self.socket.send(dumps({ 'msg': 'request_state', 'tag': active_tag, })) def push_commands(self, cmds): logging.debug('pushing commands...') self.socket.send(dumps({ 'msg': 'push_commands', 'cmds': map(str, cmds), })) def _on_message(self, socket, message): self._send(message) def run(self): self.socket = WebSocketApp( 'ws://127.0.0.1:{}/gtd'.format(self.port), on_message=self._on_message) self.socket.run_forever()
def run_stream(self): if not self.active_ws or not self.listen_key: self.listen_key = self.get_listenkey()["listenKey"] url = f"{self.base}{self.path}?streams={self.listen_key}" ws = WebSocketApp( url, on_open=self.on_open, on_error=self.on_error, on_close=self.close_stream, on_message=self.on_message, ) ws.run_forever()
def _handle_call(self, channel): dump = self._open_dumb(channel) ws = WebSocketApp(self._config["stt"]["ari_websocket_stream"], header={"Channel-ID": channel.id}, subprotocols=["stream-channel"], on_error=self._on_error, on_message=functools.partial(self._on_message, channel=channel, dump=dump), on_close=functools.partial(self._on_close, channel=channel, dump=dump)) logger.critical("websocket client started") ws.run_forever()
class WebSocketClient(AbstractWebSocketClient): __instance: Optional['WebSocketClient'] = None def __init__(self, logger: AbstractLogger = Logger()): if WebSocketClient.__instance: raise Exception('Use get_instance() instead!') self.__ws = WebSocketApp( 'wss://jqbx.fm/socket.io/?EIO=3&transport=websocket') self.__logger = logger WebSocketClient.__instance = self @staticmethod def get_instance() -> 'WebSocketClient': if WebSocketClient.__instance is None: WebSocketClient() return WebSocketClient.__instance def register(self, on_open: Callable[[], None], on_message: Callable[[WebSocketMessage], None], on_error: Callable[[Any], None], on_close: Callable[[], None]) -> None: self.__ws.on_open = lambda _: on_open() self.__ws.on_message = lambda _, raw_message: on_message( self.__parse(raw_message)) def run(self) -> None: self.__ws.run_forever() def send(self, web_socket_message: WebSocketMessage) -> None: self.__logger.info('Outgoing Message', web_socket_message.as_dict()) serialized = str(web_socket_message.code) array_part = [ x for x in [web_socket_message.label, web_socket_message.payload] if x ] if array_part: serialized += json.dumps(array_part) self.__ws.send(serialized) @staticmethod def __parse(raw_message: str) -> WebSocketMessage: stripped = raw_message.strip() parts = stripped.split('[', 1) label = None payload = None if len(parts) > 1: json_array = json.loads('[%s' % parts[1]) label = json_array[0] payload = None if len(json_array) == 1 else json_array[1] return WebSocketMessage(int(parts[0]), label, payload)
def hack(trivia_hq, google_cse): from requests import get from dateutil.parser import parse from selenium import webdriver from atexit import register from websocket import WebSocketApp headers = { 'User-Agent': 'hq-viewer/1.2.4 (iPhone; iOS 11.1.1; Scale/3.00)', 'Authorization': 'Bearer ' + trivia_hq.bearer_token, 'x-hq-client': 'iOS/1.2.4 b59' } try: response = get( 'https://api-quiz.hype.space/shows/now?type=hq&userId=' + trivia_hq.user_id, headers).json() except Exception as e: quit('Server error fetching show schedule: ' + repr(e)) nextShowTime = parse(response['nextShowTime'] ) if response['nextShowTime'] else datetime.now(utc) nextShowPrize = response['nextShowPrize'] broadcast = response['broadcast'] if broadcast: streamUrl = broadcast['streamUrl'] socketUrl = broadcast['socketUrl'].replace('https', 'wss', 1) else: quit('Broadcast ended. Next show at ' + str(nextShowTime.astimezone(LOCAL)) + ' for ' + nextShowPrize + '.') #system('/Applications/VLC.app/Contents/MacOS/VLC ' + streamUrl + ' &') n_drivers = N_QUESTIONS + 1 globals()['DRIVERS'] = [webdriver.Chrome() for _ in range(n_drivers)] register(kill_drivers, DRIVERS) triviaClient = WebSocketApp(socketUrl, on_open=on_open, on_message=on_message, on_error=on_error, on_close=on_close, header=headers) globals()['CREDENTIALS'] = google_cse while True: triviaClient.run_forever()
class UpbitReal: def __init__(self, request, callback=print): self.request = request self.callback = callback self.ws = WebSocketApp( url="wss://api.upbit.com/websocket/v1", on_message=lambda ws, msg: self.on_message(ws, msg), on_error=lambda ws, msg: self.on_error(ws, msg), on_close=lambda ws: self.on_close(ws), on_open=lambda ws: self.on_open(ws)) self.running = False def on_message(self, ws, msg): msg = json.loads(msg.decode('utf-8')) # result = dict() now = datetime.datetime.now() # result['time'] = msg['tdt'] + msg['ttm'] -> UTC # result['time'] = str(now) # result['cur_price'] = msg['tp'] # result['acc_volume'] = msg['atv'] # result = json.dumps(result) # print(type(result)) conn.hmset("bitData", { "time": str(now), "curPrice": msg['tp'], "accVolume": msg['atv'] }) # self.callback(msg) def on_error(self, ws, msg): self.callback(msg) def on_close(self, ws): self.callback("closed") self.running = False def on_open(self, ws): th = Thread(target=self.activate, daemon=True) th.start() def activate(self): self.ws.send(self.request) while self.running: time.sleep(1) self.ws.close() def start(self): self.running = True self.ws.run_forever()
def ws_main_loop(username, password): ws = WebSocketApp(BASE_URL + UPDATE, header=[ 'X-User: '******'X-Pass: '******'X-Client-Version: ' + CLIENT_VERSION ], on_open=on_open, on_close=on_close, on_message=on_msg, on_error=on_error, on_pong=on_pong) self.ws = ws ws.run_forever(ping_interval=self.ping_interval, ping_timeout=self.ping_timeout, sslopt=sslopt_ca_certs) self.registry.emit('ws thread return')
def run_socket(self, rpc, process_monitor, push_interval, url, token): while True: try: print('WebsocketManager.run_socket: create_connection') WebSocketConnection.process_monitor = process_monitor WebSocketConnection.push_interval = push_interval WebSocketConnection.rpc = rpc ws = WebSocketApp('{0}/supervisor/'.format(url.strip('/')), header=['authorization: {0}'.format(token)], on_message=WebSocketConnection.on_message, on_error=WebSocketConnection.on_error, on_open=WebSocketConnection.on_open, on_close=WebSocketConnection.on_close) ws.run_forever() except Exception as e: print("Exception: %s" % e) time.sleep(60) # Wait 60 seconds before attemping to reconnect
def start(c:Config): from websocket import WebSocketApp from simplejson import loads,dumps from rx import Observable from rx.subjects import Subject from rx.concurrency import NewThreadScheduler from .notifier import Slack, Jenkins slack = Slack(config=c, log=log) jenkins = Jenkins(config=c, log=log) # create streams stream = Subject() events = (stream .map(loads).filter(lambda p: p.get('name') == 'resource.change') .map(lambda payload: payload.get('data',{})) .filter(lambda data: isinstance(data, dict)) .map(lambda data: data.get('resource',{})) .filter(lambda res: isinstance(res,dict)) .filter(lambda res: res.get('type') in SUPPORTED_TYPES) .map(from_resource) .distinct_until_changed()) slack_events = (events .filter(lambda event: event.type == 'service' and event.state == 'upgraded')) jenkins_events = (events .filter(lambda event: event.type == 'host' and event.state == 'reconnecting')) # subscribe async = NewThreadScheduler() subs = [] subs += [events.subscribe(log.debug)] subs += [slack_events.observe_on(async).subscribe(slack.notify)] subs += [jenkins_events.observe_on(async).subscribe(jenkins.notify)] # connect to websocket ws = WebSocketApp(c.RANCHER_WS_URL, on_message = lambda ws,msg: stream.on_next(msg), on_error = lambda ws,err: log.error(err), on_close = lambda ws: log.info('Websocket connection closed'), on_open = lambda ws: log.info('Websocket connection opened'), header = {"Authorization": c.RANCHER_WS_AUTH}) ws.run_forever() # clean subscriptions for sub in subs: sub.dispose()
def main(): streamlist = list() streamlist.append('btcusdt@depth') streamlist.append('btcusdt@trade') if len(streamlist) > 1: stream_string = '/stream?streams=' for stream in streamlist: stream_string = '%s%s/' % (stream_string, stream) else: stream_string = '/ws/%s' % streamlist[0] ws = WebSocketApp('%s%s' % (WSS_URL, stream_string), on_message=on_message, on_error=on_error, on_close=on_close) ws.on_open = on_open while True: ws.run_forever(http_proxy_host=proxy_url, http_proxy_port=proxy_port)
class Firebase(Thread): def __init__(self): super(Firebase, self).__init__() self.sock = WebSocketApp(url='ws://%s.ws' % BASE_URL, on_message=self.msg_handler, on_open=self.connect_handler, on_error=self.err_handler) self.ready = Event() self._rn = 0 def run(self): self.sock.run_forever() def connect_handler(self, sock): sock.send(u'version=1') def err_handler(self, exc): print exc def send(self, msg): self.sock.send(msg) @property def rn(self): self._rn = self._rn + 1 return self._rn def listen_to_channel(self, channel): print 'listening to %s' % channel self.send('1') data = { "rn": "%i" % self.rn, "payload": { "action": "listen", "path": channel } } self.send(json.dumps(data)) def close(self): self.sock.close()
def connect(self): self.ended = True self.hadCtrl = False self.reconnectTime = time() if self.timeout: self.timeout.cancel() ws = WebSocketApp(self.endpoint.replace('https:','wss:') + '/chatapi/v1/chatnow', on_open = self.authentify, on_message = self.parse, on_error = self.error, on_close = self.close, header={'User-Agent': 'ChatMan/1 (Android) '}) self.timeout = Timer(80, self.ratamioche) self.timeout.daemon = True self.timeout.start() self.ws = ws ws.run_forever(sslopt=sslopt_ca_certs, ping_timeout=90)
class chatUser(): messageList = None def __init__(self, info, eventList, sleepTime, waitTime, id): self.actionList = eventList self.sleepTime = sleepTime self.id = id self.messageList = [] time.sleep(waitTime) print('\nweb socket-', id, ' setting: ', info, ' start_at: ', int(time.time() * 1000)) self.ws = WebSocketApp(info, on_message=self.on_message, on_error=self.on_error, on_close=self.on_close) self.ws.on_open = self.on_open self.ws.run_forever() def __del__(self): print('call del fun') self.messageList = None self.actionList = None def on_message(self, message): data = json.loads(message) pprint(data) self.messageList.insert(0, data) def on_error(self, error): print('get ', self.id, ' error: ', error) def on_close(self): print("webSocket-", self.id, " has been closed at ", int(time.time())) def on_open(self): for i in self.actionList: pprint(i) waitTime = i.pop('sleep') time.sleep(waitTime) self.ws.send(json.dumps(i)) time.sleep(self.sleepTime)
def main(server, key): for i in range(10): sys.stdout.write('Connecting... \r') sys.stdout.flush() try: ws = WebSocketApp(server, on_message=on_message, on_error=on_error, on_close=on_close, on_open=wrapper(key)) ws.run_forever(ping_interval=15) except KeyboardInterrupt: break except: pass time.sleep(i * 1.5 + 1.5) else: click.echo(click.style('Failed to reconnect.', fg='red')) os._exit(1)
class Client(object): def __init__(self, server, token=""): "Initialize" self.server = server self.token = token self.callbacks = {} self.ws = None def send(self, path, value): "Send msg (a dict) to the server" msg = {"key": self.token} set_value(msg, path, value) if not self.ws: return self.ws.send(json.dumps(msg)) def start(self): "Start websocket" log.info("Starting websocket") self.ws = WebSocketApp(self.server, [], self.cb_on_open, self.cb_on_message, self.cb_on_error, self.cb_on_close) self.ws.run_forever() def on_message(self, path): "Decore a funcion to make it a callback" def decorator(f): self.callbacks[path] = f return decorator def cb_on_message(self, ws, message): "Dispatch messages to callbacks" for path in self.callbacks: value = get_value(json.loads(message), path) if value != {}: self.callbacks[path](value) def cb_on_error(self, ws, error): "Restart websocket" log.error("Error: %s", error) time.sleep(1) log.info("Reconnecting...") self.start() def cb_on_close(self, ws): "On connection close, cleanup things" log.info("Connection closed") def cb_on_open(self, ws): "Send empty jsons to keep alive the connection, on an separate thread" def channel(): while True: ws.send("{}") # ping to avoid timeout time.sleep(15) Thread(target=channel).start()
class Slack(Base): """Provide bot for Slack.""" def __init__(self, token: str = '', plugins: Iterable[PluginConfig] = None, max_workers: int = None) -> None: """Initializer. :param token: Access token provided by Slack. :param plugins: List of plugin modules. :param max_workers: Optional number of worker threads. :return: None """ super().__init__(plugins=plugins, max_workers=max_workers) self.client = self.setup_client(token=token) self.message_id = 0 self.ws = None # type: WebSocketApp self.connect_attempt_count = 0 def setup_client(self, token: str) -> SlackClient: """Setup ClackClient and return its instance. :param token: Slack access token. :return: SlackClient instance """ return SlackClient(token=token) def connect(self) -> None: """Connect to Slack websocket server and start interaction. :return: None """ while self.connect_attempt_count < 10: try: self.connect_attempt_count += 1 self.try_connect() except KeyboardInterrupt: break except Exception as e: logging.error(e) time.sleep(self.connect_attempt_count) else: logging.error("Attempted 10 times, but all failed. Quitting.") def try_connect(self) -> None: """Try establish connection with Slack websocket server.""" try: response = self.client.get('rtm.start') if 'url' not in response: raise Exception("url is not in the response. %s" % response) except Exception as e: raise SarahSlackException( "Slack request error on /rtm.start. %s" % e) else: self.ws = WebSocketApp(response['url'], on_message=self.message, on_error=self.on_error, on_open=self.on_open, on_close=self.on_close) self.ws.run_forever() def generate_schedule_job(self, command: ScheduledCommand) \ -> Optional[Callable[..., None]]: """Generate callback function to be registered to scheduler. This creates a function that execute given command and then handle the command response. If the response is SlackMessage instance, it make HTTP POST request to Slack web API endpoint. If string is returned, then it submit it to the message sending worker. :param command: ScheduledCommand object that holds job information :return: Optional callable object to be scheduled """ channels = command.schedule_config.pop('channels', []) if not channels: logging.warning( 'Missing channels configuration for schedule job. %s. ' 'Skipping.' % command.module_name) return None def job_function() -> None: ret = command() if isinstance(ret, SlackMessage): for channel in channels: # TODO Error handling data = {'channel': channel} data.update(ret.to_request_params()) self.client.post('chat.postMessage', data=data) else: for channel in channels: self.enqueue_sending_message(self.send_message, channel, str(ret)) return job_function @concurrent def message(self, _: WebSocketApp, event: str) -> None: """Receive event from Slack and dispatch it to corresponding method. :param _: WebSocketApp instance. This is not to be used here. :param event: JSON string that contains event information. :return: None """ decoded_event = json.loads(event) if 'ok' in decoded_event and 'reply_to' in decoded_event: # https://api.slack.com/rtm#sending_messages # Replies to messages sent by clients will always contain two # properties: a boolean ok indicating whether they succeeded and # an integer reply_to indicating which message they are in response # to. if decoded_event['ok'] is False: # Something went wrong with the previous message logging.error( 'Something went wrong with the previous message. ' 'message_id: %s. error: %s' % ( decoded_event['reply_to'], decoded_event.get('error', ""))) return None # TODO organize type_map = { 'hello': { 'method': self.handle_hello, 'description': "The client has successfully connected to the " "server"}, 'message': { 'method': self.handle_message, 'description': "A message was sent to a channel"}, 'user_typing': { 'description': "A channel member is typing a message"}, 'presence_change': { 'description': "A team member's presence changed"}, 'team_migration_started': { 'method': self.handle_team_migration, 'description': "The team is being migrated between servers"} } # type: EventTypeMap if 'type' not in decoded_event: # https://api.slack.com/rtm#events # Every event has a type property which describes the type of # event. logging.error("Given event doesn't have type property. %s" % event) return None if decoded_event['type'] not in type_map: logging.error('Unknown type value is given. %s' % event) return None logging.debug( '%s: %s. %s' % ( decoded_event['type'], type_map[decoded_event['type']].get('description', 'NO DESCRIPTION'), event)) method = type_map[decoded_event['type']].get('method', None) if method: method(decoded_event) return None def handle_hello(self, _: Dict) -> None: """Handle hello event. This is called when connection is established. :param _: Dictionary that represent event. This is not used here. :return: None """ self.connect_attempt_count = 0 # Reset retry count logging.info('Successfully connected to the server.') def handle_message(self, content: Dict) -> Optional[Future]: """Handle message event. :param content: Dictionary that represent event. :return: Optional Future instance that represent message sending result. """ # content # { # "type":"message", # "channel":"C06TXXXX", # "user":"******", # "text":".bmw", # "ts":"1438477080.000004", # "team":"T06TXXXXX" # } required_props = ('type', 'channel', 'user', 'text', 'ts') missing_props = [p for p in required_props if p not in content] if missing_props: logging.error('Malformed event is given. Missing %s. %s' % ( ', '.join(missing_props), content)) return None ret = self.respond(content['user'], content['text']) if isinstance(ret, SlackMessage): # TODO Error handling data = {'channel': content["channel"]} data.update(ret.to_request_params()) self.client.post('chat.postMessage', data=data) return None elif isinstance(ret, str): return self.enqueue_sending_message(self.send_message, content['channel'], ret) def handle_team_migration(self, _: Dict) -> None: """Handle team_migration_started event. https://api.slack.com/events/team_migration_started "When clients recieve this event they can immediately start a reconnection process by calling rtm.start again." :param _: Dictionary that represent event. :return: None """ logging.info("Team migration started.") def on_error(self, _: WebSocketApp, error: Exception) -> None: """Callback method called by WebSocketApp when error occurred. :param _: WebSocketApp instance that is not currently used. :param error: Exception instance :return: None """ logging.error("error %s", error) def on_open(self, _: WebSocketApp) -> None: """Callback method called by WebSocketApp on connection establishment. :param _: WebSocketApp instance that is not currently used. :return: None """ logging.info('connected') def on_close(self, _: WebSocketApp, code: int, reason: str) -> None: """Callback method called by WebSocketApp when connection is closed. :param _: WebSocketApp instance that is not currently used. :param code: Closing code described in RFC6455. https://tools.ietf.org/html/rfc6455#section-7.4 :param reason: Closing reason. :return: None """ logging.info('connection closed. code: %d. reason: %s', code, reason) def send_message(self, channel: str, text: str, message_type: str = 'message') -> None: """Send message to Slack via websocket connection. :param channel: Target channel to send message. :param text: Sending text. :param message_type: Message type. Default is "message." :return: None """ params = {'channel': channel, 'text': text, 'type': message_type, 'id': self.next_message_id()} self.ws.send(json.dumps(params)) def next_message_id(self) -> int: """Return unique ID for sending message. https://api.slack.com/rtm#sending_messages Every event should have a unique (for that connection) positive integer ID. All replies to that message will include this ID. :return: Unique ID as int """ self.message_id += 1 return self.message_id
class Slack(Base): def __init__(self, token: str = "", plugins: Sequence[PluginConfig] = None, max_workers: int = None) -> None: super().__init__(plugins=plugins, max_workers=max_workers) self.client = self.setup_client(token=token) self.message_id = 0 self.ws = None def setup_client(self, token: str) -> SlackClient: return SlackClient(token=token) def connect(self) -> None: try: response = self.client.get("rtm.start") except Exception as e: raise SarahSlackException("Slack request error on /rtm.start. %s" % e) else: if "url" not in response: raise SarahSlackException("Slack response did not contain connecting url. %s" % response) self.ws = WebSocketApp( response["url"], on_message=self.message, on_error=self.on_error, on_open=self.on_open, on_close=self.on_close, ) self.ws.run_forever() def add_schedule_job(self, command: Command) -> None: if "channels" not in command.config: logging.warning("Missing channels configuration for schedule job. %s. " "Skipping." % command.module_name) return def job_function() -> None: ret = command.execute() if isinstance(ret, SlackMessage): for channel in command.config["channels"]: # TODO Error handling data = dict({"channel": channel}) data.update(ret.to_request_params()) self.client.post("chat.postMessage", data=data) else: for channel in command.config["channels"]: self.enqueue_sending_message(self.send_message, channel, str(ret)) job_id = "%s.%s" % (command.module_name, command.name) logging.info("Add schedule %s" % id) self.scheduler.add_job(job_function, "interval", id=job_id, minutes=command.config.get("interval", 5)) @concurrent def message(self, _: WebSocketApp, event: str) -> None: decoded_event = json.loads(event) if "ok" in decoded_event and "reply_to" in decoded_event: # https://api.slack.com/rtm#sending_messages # Replies to messages sent by clients will always contain two # properties: a boolean ok indicating whether they succeeded and # an integer reply_to indicating which message they are in response # to. if decoded_event["ok"] is False: # Something went wrong with the previous message logging.error( "Something went wrong with the previous message. " "message_id: %d. error: %s" % (decoded_event["reply_to"], decoded_event["error"]) ) return # TODO organize type_map = { "hello": { "method": self.handle_hello, "description": "The client has successfully connected " "to the server", }, "message": {"method": self.handle_message, "description": "A message was sent to a channel"}, "user_typing": {"description": "A channel member is typing a " "message"}, } if "type" not in decoded_event: # https://api.slack.com/rtm#events # Every event has a type property which describes the type of # event. logging.error("Given event doesn't have type property. %s" % event) return if decoded_event["type"] not in type_map: logging.error("Unknown type value is given. %s" % event) return logging.debug( "%s: %s. %s" % (decoded_event["type"], type_map[decoded_event["type"]].get("description", "NO DESCRIPTION"), event) ) if "method" in type_map[decoded_event["type"]]: type_map[decoded_event["type"]]["method"](decoded_event) return def handle_hello(self, _: Dict) -> None: logging.info("Successfully connected to the server.") def handle_message(self, content: Dict) -> Optional[Future]: # content # { # "type":"message", # "channel":"C06TXXXX", # "user":"******", # "text":".bmw", # "ts":"1438477080.000004", # "team":"T06TXXXXX" # } required_props = ("type", "channel", "user", "text", "ts") missing_props = [p for p in required_props if p not in content] if missing_props: logging.error("Malformed event is given. Missing %s. %s" % (", ".join(missing_props), content)) return ret = self.respond(content["user"], content["text"]) if isinstance(ret, SlackMessage): # TODO Error handling data = dict({"channel": content["channel"]}) data.update(ret.to_request_params()) self.client.post("chat.postMessage", data=data) elif isinstance(ret, str): return self.enqueue_sending_message(self.send_message, content["channel"], ret) def on_error(self, _: WebSocketApp, error) -> None: logging.error(error) def on_open(self, _: WebSocketApp) -> None: logging.info("connected") def on_close(self, _: WebSocketApp) -> None: logging.info("closed") def send_message(self, channel: str, text: str, message_type: str = "message") -> None: params = {"channel": channel, "text": text, "type": message_type, "id": self.next_message_id()} self.ws.send(json.dumps(params)) def next_message_id(self) -> int: # https://api.slack.com/rtm#sending_messages # Every event should have a unique (for that connection) positive # integer ID. All replies to that message will include this ID. self.message_id += 1 return self.message_id def stop(self) -> None: super().stop() logging.info("STOP SLACK INTEGRATION") self.ws.close()
class DXJobLogStreamClient: def __init__( self, job_id, input_params=None, msg_output_format="{job} {level} {msg}", msg_callback=None, print_job_info=True ): self.job_id = job_id self.input_params = input_params self.msg_output_format = msg_output_format self.msg_callback = msg_callback self.print_job_info = print_job_info self.seen_jobs = {} self.error = False self.exception = None self.closed_code = None self.closed_reason = None self.url = "{protocol}://{host}:{port}/{job_id}/getLog/websocket".format( protocol='wss' if dxpy.APISERVER_PROTOCOL == 'https' else 'ws', host=dxpy.APISERVER_HOST, port=dxpy.APISERVER_PORT, job_id=job_id ) self._app = None def connect(self): while True: self.error = False self.exception = None self.closed_code = None self.closed_reason = None try: self._app = WebSocketApp( self.url, on_open=self.opened, on_close=self.closed, on_error=self.errored, on_message=self.received_message ) self._app.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE}) except: if not self.server_restarted(): raise finally: self._app = None if self.server_restarted(): # Instead of trying to reconnect in a retry loop with backoff, run an # API call that will do the same and block while it retries. logger.warn("Server restart, reconnecting...") time.sleep(1) dxpy.describe(self.job_id) else: break def server_restarted(self): return ( self.closed_code == 1001 and self.closed_reason == "Server restart, please reconnect later" ) def opened(self): args = { "access_token": dxpy.SECURITY_CONTEXT['auth_token'], "token_type": dxpy.SECURITY_CONTEXT['auth_token_type'] } if self.input_params: args.update(self.input_params) self._app.send(json.dumps(args)) def errored(self, exception=None): self.error = True self.exception = exception def closed(self, code=None, reason=None): if code: self.closed_code = code self.closed_reason = reason elif not self.error: self.closed_code = 1000 self.closed_reason = "Normal" elif self.exception and type(self.exception) in {KeyboardInterrupt, SystemExit}: self.closed_code = 1000 self.closed_reason = "Connection terminated by client" else: self.closed_code = 1006 self.closed_reason = str(self.exception) if self.exception else "Abnormal" if self.closed_code != 1000: try: error = json.loads(self.closed_reason) raise DXJobLogStreamingException( "Error while streaming job logs: {type}: {message}\n".format( **error ) ) except (KeyError, ValueError): raise DXJobLogStreamingException( "Error while streaming job logs: {code}: {reason}\n".format( code=self.closed_code, reason=self.closed_reason ) ) elif self.print_job_info: if self.job_id not in self.seen_jobs: self.seen_jobs[self.job_id] = {} for job_id in self.seen_jobs.keys(): self.seen_jobs[job_id] = dxpy.describe(job_id) print( get_find_executions_string( self.seen_jobs[job_id], has_children=False, show_outputs=True ) ) else: self.seen_jobs[self.job_id] = dxpy.describe(self.job_id) if self.seen_jobs[self.job_id].get('state') in {'failed', 'terminated'}: err_exit(code=3) def received_message(self, message): message_dict = json.loads(message) if ( self.print_job_info and 'job' in message_dict and message_dict['job'] not in self.seen_jobs ): self.seen_jobs[message_dict['job']] = dxpy.describe(message_dict['job']) print( get_find_executions_string( self.seen_jobs[message_dict['job']], has_children=False, show_outputs=False ) ) if ( message_dict.get('source') == 'SYSTEM' and message_dict.get('msg') == 'END_LOG' ): self._app.keep_running = False elif self.msg_callback: self.msg_callback(message_dict) else: print(self.msg_output_format.format(**message_dict))
class TracerApp(object): """ Main tracer application. """ def __init__(self, options): self.counter = 0 self.host = options.host self.port = options.port self.ios = options.ios self.page_num = options.page_num self.timeStart = time.mktime(time.localtime()) self.shouldStep = True # If we should try to single step the debugger self._isStepping = False # If we are currently inside stepping self.ws_url = None self.ws = None self._requestDetails = {} # Map of details about a request def showConnectionList(self): """ Print out list of possible debugger connections """ # Mobile safari has a different listing page if self.ios: pages_url = "http://%s:%s/listing.json" % (self.host, self.port) else: pages_url = "http://%s:%s/json" % (self.host, self.port) pages = urllib2.urlopen(pages_url) pages_data = json.loads(pages.read()) for page in pages_data: print "----------------------------------------------------------" if self.ios: print "Page: ", page.get('pageTitle') print " id: ", page.get('pageId') print " url: ", page.get('pageURL') print " debug url: ", page.get('debugURL') else: print "Page: ", page.get('title', '') print " url: ", page.get('url', '') print " ws_debug_url: ", page.get('webSocketDebuggerUrl', '') def start(self): self.ws_url = "ws://%s:%s/devtools/page/%s" % (self.host, self.port, self.page_num) self.ws = WebSocketApp(self.ws_url, on_open = self.onOpen, on_message = self.onMessage, on_error = self.onError, on_close = self.onClose, ipv6 = self.ios) self.ws.run_forever() def send(self, method, params = None): self.counter += 1 # separators is important, you'll get "Message should be in JSON format." otherwise msg_data = {"id": self.counter, "method": method} if params is not None: msg_data['params'] = params message = json.dumps(msg_data, separators=(',', ':')) print "> %s" % (message,) self.ws.send(message) def recv(self): result = self.ws.recv() print "< %s" % (result,) return result # ---- PRIMARY CALLBACKS ---- # def onOpen(self, ws): #self.send('Runtime.evaluate', {'expression': '1+1'}) #self.send('Runtime.evaluate', {'expression': 'alert("hello from python")'}) #self.send('Timeline.start', {'maxCallStackDepth': 5}) #self.send('Network.enable') #self.send('Console.enable') #self.send('Timeline.start', {'maxCallStackDepth': 5}) self.send('Debugger.enable') def onMessage(self, ws, message): # Decode message into a bunch object to make easier to access attributes # but store original message so we can get to it msg = Bunch.loads(message) msg._rawMsg = json.loads(message) if hasattr(msg, 'result'): self.handleResultMsg(msg) elif hasattr(msg, 'method'): self.handleMethodMsg(msg) else: print "UNKNOWN MSG TYPE: " self.prettyPrintMsg(msg) def onError(self, ws, error): print "error: ", error def onClose(self, ws): print "CLOSED" # --- Helpers ---- # def prettyPrintMsg(self, msg): if type(msg) in types.StringTypes: msg = json.loads(msg) elif type(msg) == Bunch: msg = msg._rawMsg print json.dumps(msg, sort_keys=True, indent=3) # --- MSG Helpers --- # def handleResultMsg(self, msg): print "RESULT: [%s]" % msg.id print json.dumps(msg._rawMsg['result'], sort_keys=True, indent=3) def handleMethodMsg(self, msg): """ Try to map method name to a local handler. get name as: 'handle' + method in camel case and no .'s """ def replace(match): return match.group()[1].upper() method = msg.method handler_name = 'handle' + re.sub('\.\w', replace, method) handler_method = getattr(self, handler_name, self.handleNotificationDefault) handler_method(msg) def handleNotificationDefault(self, msg): """ By default just print the method name. """ print self.getMethodHeader(msg) # --- Console Notification Processing --- # def handleConsoleMessageAdded(self, msg): print self.getMethodHeader(msg) cmsg = msg.params.message print " msg: [%s] %s" % (cmsg.level, cmsg.text) # --- Timeline Notification Processing -- # def handleTimelineEventRecorded(self, msg): record = msg.params.record record_raw = msg._rawMsg.get('params').get('record') print "[%s] ==[ %s:%s ]=====" % ('', #self.getDeltaTsStr(record.endTime), msg.method, record.type) print " mem: %.2f/%.2f MB" % (record.usedHeapSize / (1024.0*1024.0), record.totalHeapSize / (1024.0*1024.0)) if record.has_key('endTime'): print " duration: ", (record.endTime - record.startTime) print " data: ", json.dumps(record_raw.get('data'), indent = 2) #print " children: ", json.dumps(record_raw.get('children'), indent = 2) # --- Network Notification Processing --- # def handleNetworkDataReceived(self, msg): print self.getMethodHeader(msg) print " request: ", self.getRequestSummary(msg) print " dataLen: ", msg.params.dataLength def handleNetworkLoadingFailed(self, msg): print self.getMethodHeader(msg) print " request: ", self.getRequestSummary(msg) print " error: ", msg.params.errorText def handleNetworkLoadingFinished(self, msg): print self.getMethodHeader(msg) print " request: ", self.getRequestSummary(msg) def handleNetworkRequestServedFromCache(self, msg): print self.getMethodHeader(msg) print " request: ", self.getRequestSummary(msg) def handleNetworkRequestServedFromMemoryCache(self, msg): print self.getMethodHeader(msg) print " request: ", self.getRequestSummary(msg) print " url: ", msg.params.documentURL def handleNetworkRequestWillBeSent(self, msg): request_id = msg.params.get_first('requestId', 'identifier') self._requestDetails[request_id] = Bunch(requestId = request_id, request = msg.params.request, loaderId = msg.params.loaderId, documentUrl = msg.params.documentURL, startTs = msg.params.timestamp, initiator = msg.params.get('initiator', None), stack = msg.params.stackTrace) print self.getMethodHeader(msg) print " request: ", self.getRequestSummary(msg) print " url: ", msg.params.documentURL def handleNetworkResponseReceived(self, msg): resp = msg.params.response print self.getMethodHeader(msg) print " request: ", self.getRequestSummary(msg) print " type: ", msg.params.type print " reused: ", resp.connectionReused print " from disk: ", resp.fromDiskCache print " mime: ", resp.mimeType print " status: [%s] %s" % (resp.status, resp.statusText) def handleDebuggerDebuggerWasEnabled(self, msg): print self.getMethodHeader(msg) if self.shouldStep: self.send('Debugger.pause') # self.send('Debugger.stepInto') # self._isStepping = True def handleDebuggerPaused(self, msg): print self.getMethodHeader(msg) print " reason: ", msg.params.reason params_raw = msg._rawMsg.get('params') print " data: ", json.dumps(params_raw.get('data'), indent = 2) print " frame: ", json.dumps(params_raw.get('callFrames'), indent = 2) if self.shouldStep: self.send('Debugger.stepInto') def handleDebuggerResumed(self, msg): print self.getMethodHeader(msg) def handleDebuggerScriptParsed(self, msg): print self.getMethodHeader(msg) print json.dumps(msg._rawMsg.get('params'), indent = 2) # ---- Helpers ---- # def getMethodHeader(self, msg): return "[%s] ==[ %s ]=====" % (self.getTS(msg), msg.method) def getRequestSummary(self, msg): request_id = msg.params.get_first('requestId', 'identifier') req_record = self._requestDetails.get(request_id, None) if req_record: return "[%s] %s" % (request_id, req_record.request.url) else: return "[%s] {unknown}" % request_id def getTS(self, msg): """ Returns a timestamp string to use as prefix """ ts_value = None if hasattr(msg, 'params'): ts_value = msg.params.get('timestamp', None) if ts_value is None: return '<nots>' else: return self.getDeltaTsStr(ts_value) def getDeltaTsStr(self, ts): ts_delta = ts - self.timeStart return "%8.4f" % ts_delta
class XSocketsClient(object): def __init__(self, url, onerror = None, onopen = None, onclose = None): super(XSocketsClient, self).__init__() self.onerror = onerror self.onopen = onopen self.subscriptions = Subscriptions() self.webSocket = None self.bind(XSockets.Events.open, self._open_event_handler, opts = {"skip": True}) thread.start_new_thread(self.start, (url, onopen, onclose)) def _open_event_handler(self, data): log.DEBUG(data) data[u"clientType"] = u"RFC6455" self.connection = data self.XSocketsClientStorageGuid = data["StorageGuid"] for sub in self.subscriptions.getAll(): for callback in sub.callbacks: if sub.name and callback.state.get("options", {}).get("skip", False): continue self.trigger(Message( XSockets.Events.pubSub.subscribe, {"Event": sub.name, "Confim": False})) self.dispatchEvent(XSockets.Events.bindings.completed, self.subscriptions.getAll()) if self.onopen: self.onopen() def start(self, url, onopen, onclose): self.webSocket = ConnectionManager(url, on_message = self._on_message, on_error = self.print_error, on_close = onclose) self.webSocket.run_forever() def print_error(self, *args, **kwargs): print args, kwargs def __del__(self, *args): if self.webSocket is not None: self.webSocket.close() def _on_message(self, ws, message): cont = json.loads(message) log.DEBUG(cont) self.dispatchEvent(cont["event"], cont["data"]) if cont["event"] == XSockets.Events.onError: if self.onerror: self.onerror(message) self.dispatchEvent(cont["event"], cont["data"]) def bind(self, event, fn, opts = {}, callback = None): state = { "options": opts, "ready": self.webSocket is not None and self.webSocket.sock is not None, "confim": callback is not None } log.DEBUG("%s - %s" %(event, fn)) if state["ready"]: self.trigger(Message( XSockets.Events.pubSub.subscribe, {"Event": event, "Confim": state["confim"]})) if isinstance(fn, list): for f in fn: self.subscriptions.add(event, f, state) else: self.subscriptions.add(event, fn, state) return self on = bind subscribe = bind def trigger(self, event, json = {}, callback = None): if isinstance(event, Message): message = event else: event = event.lower() message = Message(event, json) log.DEBUG(message.to_json()) self.webSocket.send(message.to_json()) if callback is not None: callback() return self publish = trigger emit = trigger def dispatchEvent(self, event, message): if self.subscriptions.get(event) is None: return self.subscriptions.fire(event, json.loads(message)) def send(self, data, event): mes = Message(event, data) log.DEBUG(mes.to_json()) self.webSocket.send(mes.to_json())
#send('Runtime.evaluate', {'expression': '1+1'}) #send('Runtime.evaluate', {'expression': 'alert("hello from python")'}) #send('Timeline.start', {'maxCallStackDepth': 5}) send('Network.enable') gCounter = 0 def send(method, params = None): global gCounter gCounter += 1 # separators is important, you'll get "Message should be in JSON format." otherwise msg_data = {"id": gCounter, "method": method} if params is not None: msg_data['params'] = params message = json.dumps(msg_data, separators=(',', ':')) print "> %s" % (message,) ws.send(message) def recv(): result = ws.recv() print "< %s" % (result,) ws = WebSocketApp(ws_url, on_open = on_open, on_message = on_message, on_error = on_error, on_close = on_close) ws.run_forever()