Example #1
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)
Example #2
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)
Example #3
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))
Example #4
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))
Example #5
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)
Example #6
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)
Example #7
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))
Example #8
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)
Example #9
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()
Example #10
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=(',', ':')))
Example #11
0
 async def ping_loop(self):
     if self.verbose:
         self.print(Exchange.iso8601(Exchange.milliseconds()), 'ping loop')
     pass