async def create(cls,
                  server_address: str,
                  credentials: bytes,
                  p2p: P2PConnection,
                  timeout: int = IO_TIMEOUT,
                  loop: asyncio.AbstractEventLoop = None):
     instance = cls(server_address, credentials, p2p, timeout, loop)
     await instance._connector.open()
     payload = await instance._connector.read(timeout=timeout)
     context = Message.deserialize(payload.decode())
     msg_type = context.get('@type', None)
     if msg_type is None:
         raise RuntimeError('message @type is empty')
     elif msg_type != cls.MSG_TYPE_CONTEXT:
         raise RuntimeError('message @type is empty')
     else:
         await instance._setup(context)
     return instance
 def from_url(cls, url: str) -> ConnProtocolMessage:
     matches = re.match("(.+)?c_i=(.+)", url)
     if not matches:
         raise SiriusInvalidMessage("Invite string is improperly formatted")
     msg = Message.deserialize(
         base64.urlsafe_b64decode(matches.group(2)).decode('utf-8'))
     if msg.protocol != cls.PROTOCOL:
         raise SiriusInvalidMessage('Unexpected protocol "%s"' %
                                    msg.type.protocol)
     if msg.name != cls.NAME:
         raise SiriusInvalidMessage('Unexpected protocol name "%s"' %
                                    msg.type.name)
     label = msg.pop('label')
     if label is None:
         raise SiriusInvalidMessage('label attribute missing')
     recipient_keys = msg.pop('recipientKeys')
     if recipient_keys is None:
         raise SiriusInvalidMessage('recipientKeys attribute missing')
     endpoint = msg.pop('serviceEndpoint')
     if endpoint is None:
         raise SiriusInvalidMessage('serviceEndpoint attribute missing')
     routing_keys = msg.pop('routingKeys', [])
     return Invitation(label, recipient_keys, endpoint, routing_keys, **msg)
 async def _reopen(self):
     await self._connector.reopen()
     payload = await self._connector.read(timeout=1)
     context = Message.deserialize(payload.decode())
     await self._setup(context)