예제 #1
0
 def on_close(self, code):
     if self.verbose:
         self.print(Exchange.iso8601(Exchange.milliseconds()), 'on_close', code)
     if not self.error:
         self.reset(NetworkError(code))
     self.on_close_callback(self, code)
     if not self.closed():
         ensure_future(self.close(code))
예제 #2
0
 def on_error(self, error):
     if self.verbose:
         self.print(Exchange.iso8601(Exchange.milliseconds()), 'on_error', error)
     self.error = error
     self.reset(error)
     self.on_error_callback(self, error)
     if not self.closed():
         ensure_future(self.close(1006))
예제 #3
0
 def handle_text_or_binary_message(self, data):
     if self.verbose:
         self.print(Exchange.iso8601(Exchange.milliseconds()), 'message',
                    data)
     if isinstance(data, bytes):
         data = data.decode()
     decoded = json.loads(data) if Exchange.is_json_encoded_object(
         data) else data
     self.on_message_callback(self, decoded)
예제 #4
0
 async def open(self, session, backoff_delay=0):
     # exponential backoff for consequent connections if necessary
     if backoff_delay:
         await sleep(backoff_delay)
     if self.verbose:
         self.print(Exchange.iso8601(Exchange.milliseconds()),
                    'connecting to', self.url, 'with timeout',
                    self.connectionTimeout, 'ms')
     self.connectionStarted = Exchange.milliseconds()
     try:
         coroutine = self.create_connection(session)
         self.connection = await wait_for(
             coroutine, timeout=int(self.connectionTimeout / 1000))
         self.connecting = False
         if self.verbose:
             self.print(Exchange.iso8601(Exchange.milliseconds()),
                        'connected')
         self.connected.resolve(self.url)
         # run both loops forever
         await gather(self.ping_loop(), self.receive_loop())
     except TimeoutError as e:
         # connection timeout
         error = RequestTimeout('Connection timeout')
         if self.verbose:
             self.print(Exchange.iso8601(Exchange.milliseconds()),
                        'RequestTimeout', error)
         self.on_error(error)
     except Exception as e:
         # connection failed or rejected (ConnectionRefusedError, ClientConnectorError)
         error = NetworkError(e)
         if self.verbose:
             self.print(Exchange.iso8601(Exchange.milliseconds()),
                        'NetworkError', error)
         self.on_error(error)
예제 #5
0
 def on_close(self, code):
     if self.verbose:
         self.print(Exchange.iso8601(Exchange.milliseconds()), 'on_close',
                    code)
     if not self.error:
         self.reset(
             NetworkError(
                 'Connection closed by remote server, closing code ' +
                 str(code)))
     self.on_close_callback(self, code)
     if not self.closed():
         ensure_future(self.close(code))
예제 #6
0
 async def receive_loop(self):
     if self.verbose:
         self.print(Exchange.iso8601(Exchange.milliseconds()), 'receive loop')
     while not self.closed():
         try:
             message = await self.receive()
             # self.print(Exchange.iso8601(Exchange.milliseconds()), 'received', message)
             self.handle_message(message)
         except Exception as e:
             error = NetworkError(str(e))
             if self.verbose:
                 self.print(Exchange.iso8601(Exchange.milliseconds()), 'receive_loop', 'Exception', error)
             self.reset(error)
예제 #7
0
 def __init__(self,
              url,
              on_message_callback,
              on_error_callback,
              on_close_callback,
              config={}):
     defaults = {
         'url': url,
         'futures': {},
         'subscriptions': {},
         'on_message_callback': on_message_callback,
         'on_error_callback': on_error_callback,
         'on_close_callback': on_close_callback,
     }
     settings = {}
     settings.update(defaults)
     settings.update(config)
     for key in settings:
         if hasattr(self, key) and isinstance(getattr(self, key), dict):
             setattr(
                 self, key,
                 Exchange.deep_extend(getattr(self, key), settings[key]))
         else:
             setattr(self, key, settings[key])
     # connection-related Future
     self.connected = Future()
예제 #8
0
 def safe_decimal(dictionary, key, default_value=None):
     value = default_value
     try:
         if Exchange.key_exists(dictionary, key):
             value = Decimal(str(dictionary[key]))
     except ValueError as e:
         value = default_value
     return value
예제 #9
0
 async def ping_loop(self):
     if self.verbose:
         self.print(Exchange.iso8601(Exchange.milliseconds()), 'ping loop')
     while self.keepAlive and not self.closed():
         now = Exchange.milliseconds()
         self.lastPong = now if self.lastPong is None else self.lastPong
         if (self.lastPong + self.keepAlive * self.maxPingPongMisses) < now:
             self.on_error(
                 RequestTimeout(
                     'Connection to ' + self.url +
                     ' timed out due to a ping-pong keepalive missing on time'
                 ))
         # the following ping-clause is not necessary with aiohttp's built-in ws
         # since it has a heartbeat option (see create_connection above)
         # however some exchanges require a text-type ping message
         # therefore we need this clause anyway
         else:
             if self.ping:
                 await self.send(self.ping(self))
             else:
                 await self.connection.ping()
         await sleep(self.keepAlive / 1000)
예제 #10
0
 async def close(self, code=1000):
     if self.verbose:
         self.print(Exchange.iso8601(Exchange.milliseconds()), 'closing',
                    code)
     if not self.closed():
         await self.connection.close()
예제 #11
0
 def send(self, message):
     if self.verbose:
         self.print(Exchange.iso8601(Exchange.milliseconds()), 'sending',
                    message)
     return self.connection.send_str(message if isinstance(
         message, str) else json.dumps(message, separators=(',', ':')))
예제 #12
0
 def handle_message(self, message):
     # self.print(Exchange.iso8601(Exchange.milliseconds()), message)
     if message.type == WSMsgType.TEXT:
         self.handle_text_or_binary_message(message.data)
     elif message.type == WSMsgType.BINARY:
         data = message.data
         if self.gunzip:
             data = gunzip(data)
         elif self.inflate:
             data = inflate(data)
         self.handle_text_or_binary_message(data)
     # autoping is responsible for automatically replying with pong
     # to a ping incoming from a server, we have to disable autoping
     # with aiohttp's websockets and respond with pong manually
     # otherwise aiohttp's websockets client won't trigger WSMsgType.PONG
     elif message.type == WSMsgType.PING:
         if self.verbose:
             self.print(Exchange.iso8601(Exchange.milliseconds()), 'ping',
                        message)
         ensure_future(self.connection.pong())
     elif message.type == WSMsgType.PONG:
         self.lastPong = Exchange.milliseconds()
         if self.verbose:
             self.print(Exchange.iso8601(Exchange.milliseconds()), 'pong',
                        message)
         pass
     elif message.type == WSMsgType.CLOSE:
         if self.verbose:
             self.print(Exchange.iso8601(Exchange.milliseconds()), 'close',
                        self.closed(), message)
         self.on_close(message.data)
     elif message.type == WSMsgType.CLOSED:
         if self.verbose:
             self.print(Exchange.iso8601(Exchange.milliseconds()), 'closed',
                        self.closed(), message)
         self.on_close(1000)
     elif message.type == WSMsgType.ERROR:
         if self.verbose:
             self.print(Exchange.iso8601(Exchange.milliseconds()), 'error',
                        message)
         error = NetworkError(str(message))
         self.on_error(error)
예제 #13
0
 async def ping_loop(self):
     if self.verbose:
         self.print(Exchange.iso8601(Exchange.milliseconds()), 'ping loop')
     pass
예제 #14
0
 def parse_json(self, http_response):
     try:
         if Exchange.is_json_encoded_object(http_response):
             return simplejson.loads(http_response, use_decimal=True)
     except ValueError:  # superclass of JsonDecodeError (python2)
         pass
예제 #15
0
 def safe_decimal_2(dictionary, key1, key2, default_value=None):
     return Exchange.safe_either(CCXTExtension.safe_decimal, dictionary,
                                 key1, key2, default_value)