示例#1
0
文件: check.py 项目: si618/pi-time
def check_url(config, section):
    if 'url' in config:
        url = config['url']
        if type(url) != six.text_type:
            raise TypeError("'url' in {} configuration must be str, "
                            "but got {}".format(section, type(url).__name__))
        try:
            parseWsUrl(url)
        except Exception as e:
            raise ValueError("Invalid 'url' in {} configuration: {}".format(
                section, e))
    else:
        raise ValueError("'url' required in {} configuration"
                         .format(section))
示例#2
0
        def setupService(self):
            """
            Setup the application component.
            """
            isSecure, host, port, resource, path, params = parseWsUrl(self.url)

            # factory for use ApplicationSession
            def create():
                cfg = ComponentConfig(self.realm, self.extra)
                session = self.make(cfg)
                session.debug_app = self.debug_app
                return session

            # create a WAMP-over-WebSocket transport client factory
            transport_factory = self.factory(create, url=self.url,
                                             debug=self.debug, debug_wamp=self.debug_wamp)

            # setup the client from a Twisted endpoint

            if isSecure:
                from twisted.application.internet import SSLClient
                clientClass = SSLClient
            else:
                from twisted.application.internet import TCPClient
                clientClass = TCPClient

            client = clientClass(host, port, transport_factory)
            client.setServiceParent(self)
    def getMapUpdaterComponentService(self, url, realm, mapUpdater):
        def create(config):
            try:
                session = MapUpdaterComponent(mapUpdater, config)
            except Exception as e:
                # the app component could not be created .. fatal
                print(e)
            else:
                session.debug_app = True
                return session

        sessionFactory = ApplicationSessionFactory(
            ComponentConfig(realm, None))
        sessionFactory.session = create

        transportFactory = WampWebSocketClientFactory(
            sessionFactory, url=url)
        transportFactory.noisy = False
        transportFactory.autoPingInterval = 30
        transportFactory.autoPingTimeout = 30

        isSecure, host, port, resource, path, params = parseWsUrl(url)

        endpoint = HostnameEndpoint(reactor, host.encode('utf8'), port)
        if isSecure:
            contextFactory = optionsForClientTLS(hostname=host)
            endpoint = wrapClientTLS(contextFactory, endpoint)
        return ClientService(endpoint, transportFactory)
示例#4
0
    def start(self, url, loop=None, debug=False, debug_wamp=False):
        """
        Starts a WAMP session based on the arguments above.
        """
        logging.info('wamp_session.start')

        if loop is None:
            loop = asyncio.get_event_loop()
        self.loop = loop

        isSecure, host, port, resource, path, params = parseWsUrl(url)

        transport_factory = WampWebSocketClientFactory(
            lambda: self, url=url, serializers=None,
            debug=debug, debug_wamp=debug_wamp)

        connection = loop.create_connection(
            transport_factory,
            host,
            port,
            ssl=isSecure)

        asyncio.async(connection)

        logging.info('start_wamp_session finished.')

        return loop
    def register(self):
        def create():
            cfg = ComponentConfig(
                    self._realm,
                    extra={"dts": self._dts, "loop": self._loop, "log": self._log}
                    )

            # Set the asyncio loop for txaio
            txaio.config.loop = self._loop
            self._app = WampDtsMockApplication(cfg)
            self._app.debug_app = True

            return self._app

        isSecure, host, port, resource, path, params = parseWsUrl(self._url)
        transport_factory = WampWebSocketClientFactory(
                create, url=self._url,
                serializers=None, debug=True, debug_wamp=True,
                )

        while True:
            try:
                create_conn = self._loop.create_connection(transport_factory, host, port)
                (transport, protocol) = yield from create_conn
                self._log.debug("Connected to crossbar.io")
                break
            except ConnectionRefusedError:
                self._log.error("ConnectionRefusedError: sleeping for a second and retrying")
                yield from asyncio.sleep(1, self._loop)
示例#6
0
文件: wamp.py 项目: goks/Winky
        def setupService(self):
            """
            Setup the application component.
            """
            is_secure, host, port, resource, path, params = parseWsUrl(self.url)

            # factory for use ApplicationSession
            def create():
                cfg = ComponentConfig(self.realm, self.extra)
                session = self.make(cfg)
                session.debug_app = self.debug_app
                return session

            # create a WAMP-over-WebSocket transport client factory
            transport_factory = self.factory(create, url=self.url, debug=self.debug)

            # setup the client from a Twisted endpoint

            if is_secure:
                from twisted.application.internet import SSLClient
                ctx = self.context_factory
                if ctx is None:
                    from twisted.internet.ssl import optionsForClientTLS
                    ctx = optionsForClientTLS(host)
                client = SSLClient(host, port, transport_factory, contextFactory=ctx)
            else:
                if self.context_factory is not None:
                    raise Exception("context_factory specified on non-secure URI")
                from twisted.application.internet import TCPClient
                client = TCPClient(host, port, transport_factory)

            client.setServiceParent(self)
示例#7
0
def check_transport_websocket(transport):
   for k in transport:
      if k not in ['type', 'endpoint', 'url', 'debug', 'options']:
         raise Exception("encountered unknown attribute '{}' in WebSocket transport configuration".format(k))

   if not 'endpoint' in transport:
      raise Exception("missing mandatory attribute 'endpoint' in WebSocket transport item\n\n{}".format(pformat(transport)))

   check_endpoint_listen(transport['endpoint'])

   if 'options' in transport:
      check_websocket_options(transport[options])

   if 'debug' in transport:
      debug = transport['debug']
      if type(debug) != bool:
         raise Exception("'debug' in WebSocket transport configuration must be boolean ({} encountered)".format(type(debug)))

   if 'url' in transport:
      url = transport['url']
      if type(url) not in [str, unicode]:
         raise Exception("'url' in WebSocket transport configuration must be str ({} encountered)".format(type(url)))
      try:
         u = parseWsUrl(url)
      except Exception as e:
         raise Exception("invalid 'url' in WebSocket transport configuration : {}".format(e))
示例#8
0
   def run(self, make):
      """
      Run the application component.

      :param make: A factory that produces instances of :class:`autobahn.asyncio.wamp.ApplicationSession`
                   when called with an instance of :class:`autobahn.wamp.types.ComponentConfig`.
      :type make: callable
      """
      ## 1) factory for use ApplicationSession
      def create():
         cfg = ComponentConfig(self.realm, self.extra)
         try:
            session = make(cfg)
         except Exception as e:
            ## the app component could not be created .. fatal
            print(e)
            asyncio.get_event_loop().stop()
         else:
            session.debug_app = self.debug_app
            return session

      isSecure, host, port, resource, path, params = parseWsUrl(self.url)
      
      ## 2) create a WAMP-over-WebSocket transport client factory
      transport_factory = WampWebSocketClientFactory(create, url = self.url,
         debug = self.debug, debug_wamp = self.debug_wamp)

      ## 3) start the client
      loop = asyncio.get_event_loop()
      coro = loop.create_connection(transport_factory, host, port)
      loop.run_until_complete(coro)

      ## 4) now enter the asyncio event loop
      loop.run_forever()
      loop.close()
示例#9
0
    def __init__(self, url, username="", password="",
                 proto=GrapheneWebsocketProtocol):
        """ Open A GrapheneWebsocket connection that can handle
            notifications though asynchronous calls.

            :param str url: Url to the websocket server
            :param str username: Username for login
            :param str password: Password for login
            :param GrapheneWebsocketProtocol proto: (optional) Protocol that inherits ``GrapheneWebsocketProtocol``
        """
        ssl, host, port, resource, path, params = parseWsUrl(url)
        self.url      = url
        self.username = username
        self.password = password

        # Open another RPC connection to execute calls
        GrapheneWebsocketRPC.__init__(self, url, username, password)

        # Parameters for another connection for asynchronous notifications
        self.ssl      = ssl
        self.host     = host
        self.port     = port
        self.proto    = proto
        self.proto.username = username
        self.proto.password = password
        self.objectMap = LimitedSizeDict()
        self.proto.objectMap = self.objectMap  # this is a reference
        self.factory  = None
示例#10
0
   def run(self, make, start_reactor = True):
      """
      Run the application component.

      :param make: A factory that produces instances of :class:`autobahn.asyncio.wamp.ApplicationSession`
                   when called with an instance of :class:`autobahn.wamp.types.ComponentConfig`.
      :type make: callable
      """
      from twisted.internet import reactor

      isSecure, host, port, resource, path, params = parseWsUrl(self.url)

      ## start logging to console
      if self.debug or self.debug_wamp or self.debug_app:
         log.startLogging(sys.stdout)

      ## run an embedded router if ask to start standalone
      if self.standalone:

         from autobahn.wamp.router import RouterFactory
         from autobahn.twisted.websocket import WampWebSocketServerFactory
         from twisted.internet.endpoints import serverFromString

         router_factory = RouterFactory()
         session_factory = RouterSessionFactory(router_factory)

         transport_factory = WampWebSocketServerFactory(session_factory, debug = self.debug, debug_wamp = self.debug_wamp)
         transport_factory.setProtocolOptions(failByDrop = False)

         server = serverFromString(reactor, "tcp:{}".format(port))
         server.listen(transport_factory)

      ## factory for use ApplicationSession
      def create():
         cfg = ComponentConfig(self.realm, self.extra)
         try:
            session = make(cfg)
         except Exception:
            ## the app component could not be created .. fatal
            log.err()
            reactor.stop()
         else:
            session.debug_app = self.debug_app
            return session

      ## create a WAMP-over-WebSocket transport client factory
      transport_factory = WampWebSocketClientFactory(create, url = self.url,
         debug = self.debug, debug_wamp = self.debug_wamp)

      ## start the client from a Twisted endpoint
      from twisted.internet.endpoints import clientFromString
      
      client = clientFromString(reactor, "tcp:{}:{}".format(host, port))
      client.connect(transport_factory)

      ## now enter the Twisted reactor loop
      if start_reactor:
         reactor.run()
示例#11
0
    def run(self, make):
        """
        Run the application component.

        :param make: A factory that produces instances of :class:`autobahn.asyncio.wamp.ApplicationSession`
           when called with an instance of :class:`autobahn.wamp.types.ComponentConfig`.
        :type make: callable
        """
        # 1) factory for use ApplicationSession
        def create():
            cfg = ComponentConfig(self.realm, self.extra)
            try:
                session = make(cfg)
            except Exception as e:
                # the app component could not be created .. fatal
                print(e)
                asyncio.get_event_loop().stop()
            else:
                session.debug_app = self.debug_app
                return session

        isSecure, host, port, resource, path, params = parseWsUrl(self.url)

        if self.ssl is None:
            ssl = isSecure
        else:
            if self.ssl and not isSecure:
                raise RuntimeError(
                    'ssl argument value passed to %s conflicts with the "ws:" '
                    'prefix of the url argument. Did you mean to use "wss:"?' %
                    self.__class__.__name__)
            ssl = self.ssl

        # 2) create a WAMP-over-WebSocket transport client factory
        transport_factory = WampWebSocketClientFactory(create, url=self.url, serializers=self.serializers,
                                                       debug=self.debug, debug_wamp=self.debug_wamp)

        # 3) start the client
        loop = asyncio.get_event_loop()
        txaio.use_asyncio()
        txaio.config.loop = loop
        coro = loop.create_connection(transport_factory, host, port, ssl=ssl)
        (transport, protocol) = loop.run_until_complete(coro)
        loop.add_signal_handler(signal.SIGTERM, loop.stop)

        # 4) now enter the asyncio event loop
        try:
            loop.run_forever()
        except KeyboardInterrupt:
            # wait until we send Goodbye if user hit ctrl-c
            # (done outside this except so SIGTERM gets the same handling)
            pass
        # give Goodbye message a chance to go through, if we still
        # have an active session
        if protocol._session:
            loop.run_until_complete(protocol._session.leave())
        loop.close()
示例#12
0
    def connect_ws(self, data):
        from autobahn.websocket.protocol import parseWsUrl
        (isSecure, host, port, resource, path, params) = parseWsUrl(
            data['url'])

        endpoint = SSL4ClientEndpoint(
            self.clock, host, port, ssl.ClientContextFactory())
        return endpoint.connect(
            RelayFactory(self, data, debug=self.debug))
示例#13
0
    def __init__(self, url, realm, extra=None, serializers=None, debug_app=False,
                 ssl=None, loop=None, retry_strategy=BackoffStrategy(), auto_ping_interval=10, auto_ping_timeout=27):
        """
        :param url: The WebSocket URL of the WAMP router to connect to (e.g. `ws://somehost.com:8090/somepath`)
        :type url: unicode
        :param realm: The WAMP realm to join the application session to.
        :type realm: unicode
        :param extra: Optional extra configuration to forward to the application component.
        :type extra: dict
        :param serializers: A list of WAMP serializers to use (or None for default serializers).
           Serializers must implement :class:`autobahn.wamp.interfaces.ISerializer`.
        :type serializers: list
        :param debug_app: Turn on app-level debugging.
        :type debug_app: bool
        :param ssl: An (optional) SSL context instance or a bool. See
           the documentation for the `loop.create_connection` asyncio
           method, to which this value is passed as the ``ssl=``
           kwarg.
        :type ssl: :class:`ssl.SSLContext` or bool
        :param auto_ping_interval: How often to send a keep-alive ping to the router (in seconds).
           A value of None turns off pings.
        :type auto_ping_interval: int
        :param auto_ping_timeout: Consider the connection dropped if the router does not respond to our
           ping for more than X seconds.
        :type auto_ping_timeout: int
        """
        self._url = url
        self._realm = realm
        self._extra = extra or dict()
        self._debug_app = debug_app
        self._serializers = serializers
        self._loop = loop or asyncio.get_event_loop()
        self._retry_strategy = retry_strategy
        self._closing = False
        self._auto_ping_interval = auto_ping_interval
        self._auto_ping_timeout = auto_ping_timeout

        self._isSecure, self._host, self._port, _, _, _ = parseWsUrl(url)

        if ssl is None:
            self._ssl = self._isSecure
        else:
            if ssl and not self._isSecure:
                raise RuntimeError(
                    'ssl argument value passed to %s conflicts with the "ws:" '
                    'prefix of the url argument. Did you mean to use "wss:"?' %
                    self.__class__.__name__)
            self._ssl = ssl
示例#14
0
 def __init__(self, url, username, password,
              proto=GrapheneWebsocketProtocol):
     ssl, host, port, resource, path, params = parseWsUrl(url)
     GrapheneWebsocketRPC.__init__(self, url, username, password)
     self.url      = url
     self.username = username
     self.password = password
     self.ssl      = ssl
     self.host     = host
     self.port     = port
     self.proto    = proto
     self.proto.username = username
     self.proto.password = password
     self.objectMap = LimitedSizeDict()
     self.proto.objectMap = self.objectMap  # this is a reference
     self.factory  = None
示例#15
0
   def run(self, make, start_reactor = True):
      """
      Run the application component.

      :param make: A factory that produces instances of :class:`autobahn.asyncio.wamp.ApplicationSession`
         when called with an instance of :class:`autobahn.wamp.types.ComponentConfig`.
      :type make: callable
      """
      from twisted.internet import reactor

      isSecure, host, port, resource, path, params = parseWsUrl(self.url)

      ## start logging to console
      if self.debug or self.debug_wamp or self.debug_app:
         log.startLogging(sys.stdout)

      ## factory for use ApplicationSession
      def create():
         cfg = ComponentConfig(self.realm, self.extra)
         try:
            session = make(cfg)
         except Exception:
            ## the app component could not be created .. fatal
            log.err()
            reactor.stop()
         else:
            session.debug_app = self.debug_app
            return session

      ## create a WAMP-over-WebSocket transport client factory
      transport_factory = WampWebSocketClientFactory(create, url = self.url,
         debug = self.debug, debug_wamp = self.debug_wamp)

      ## start the client from a Twisted endpoint
      from twisted.internet.endpoints import clientFromString

      if isSecure:
         endpoint_descriptor = "ssl:{0}:{1}".format(host, port)
      else:
         endpoint_descriptor = "tcp:{0}:{1}".format(host, port)

      client = clientFromString(reactor, endpoint_descriptor)
      client.connect(transport_factory)

      ## now enter the Twisted reactor loop
      if start_reactor:
         reactor.run()
示例#16
0
    def run(self, make):
        """
        Run the application component.

        :param make: A factory that produces instances of :class:`autobahn.asyncio.wamp.ApplicationSession`
           when called with an instance of :class:`autobahn.wamp.types.ComponentConfig`.
        :type make: callable
        """
        # 1) factory for use ApplicationSession
        def create():
            cfg = ComponentConfig(self.realm, self.extra)
            try:
                session = make(cfg)
            except Exception as e:
                # the app component could not be created .. fatal
                print(e)
                asyncio.get_event_loop().stop()
            else:
                session.debug_app = self.debug_app
                return session

        isSecure, host, port, resource, path, params = parseWsUrl(self.url)

        if self.ssl is None:
            ssl = isSecure
        else:
            if self.ssl and not isSecure:
                raise RuntimeError(
                    'ssl argument value passed to %s conflicts with the "ws:" '
                    'prefix of the url argument. Did you mean to use "wss:"?' %
                    self.__class__.__name__)
            ssl = self.ssl

        # 2) create a WAMP-over-WebSocket transport client factory
        transport_factory = WampWebSocketClientFactory(create, url=self.url, serializers=self.serializers,
                                                       debug=self.debug, debug_wamp=self.debug_wamp)

        # 3) start the client
        loop = asyncio.get_event_loop()
        txaio.use_asyncio()
        txaio.config.loop = loop
        coro = loop.create_connection(transport_factory, host, port, ssl=ssl)
        loop.run_until_complete(coro)

        # 4) now enter the asyncio event loop
        loop.run_forever()
        loop.close()
示例#17
0
def check_transport_web_path_service_websocket(config):
   if 'options' in config:
      check_websocket_options(config['options'])

   if 'debug' in config:
      debug = config['debug']
      if type(debug) != bool:
         raise Exception("'debug' in WebSocket configuration must be boolean ({} encountered)".format(type(debug)))

   if 'url' in config:
      url = config['url']
      if type(url) not in [str, unicode]:
         raise Exception("'url' in WebSocket configuration must be str ({} encountered)".format(type(url)))
      try:
         u = parseWsUrl(url)
      except Exception as e:
         raise Exception("invalid 'url' in WebSocket configuration : {}".format(e))
示例#18
0
def check_connecting_transport_websocket(transport):
   """
   Check a connecting WebSocket-WAMP transport configuration.

   :param transport: The configuration item to check.
   :type transport: dict
   """
   for k in transport:
      if k not in ['id', 'type', 'endpoint', 'url', 'serializers', 'debug', 'options']:
         raise Exception("encountered unknown attribute '{}' in WebSocket transport configuration".format(k))

   if 'id' in transport:
      check_id(transport['id'])

   if not 'endpoint' in transport:
      raise Exception("missing mandatory attribute 'endpoint' in WebSocket transport item\n\n{}".format(pformat(transport)))

   check_connecting_endpoint(transport['endpoint'])

   if 'options' in transport:
      check_websocket_options(transport['options'])

   if 'serializers' in transport:
      serializers = transport['serializers']
      if type(serializers) != list:
         raise Exception("'serializers' in WebSocket transport configuration must be list ({} encountered)".format(type(serializers)))

   if 'debug' in transport:
      debug = transport['debug']
      if type(debug) != bool:
         raise Exception("'debug' in WebSocket transport configuration must be boolean ({} encountered)".format(type(debug)))

   if not 'url' in transport:
      raise Exception("missing mandatory attribute 'url' in WebSocket transport item\n\n{}".format(pformat(transport)))

   url = transport['url']
   if type(url) != six.text_type:
      raise Exception("'url' in WebSocket transport configuration must be str ({} encountered)".format(type(url)))
   try:
      u = parseWsUrl(url)
   except Exception as e:
      raise Exception("invalid 'url' in WebSocket transport configuration : {}".format(e))
示例#19
0
def run(config_info, build_controller):
    config_push = config_info["push_server"]
    Component.init(config_push, build_controller)

    # 1) create a WAMP application session factory
    component_config = types.ComponentConfig(realm=config_push["realm"])
    session_factory = wamp.ApplicationSessionFactory(config=component_config)
    session_factory.session = Component

    # 2) create a WAMP-over-WebSocket transport client factory
    url = config_push["url"]
    transport_factory = MyClientFactory(session_factory, url=url, debug=False)

    # 3) start the client from a Twisted endpoint
    isSecure, host, port, resource, path, params = parseWsUrl(url)
    transport_factory.host = host
    transport_factory.port = port
    websocket.connectWS(transport_factory)

    # 4) now enter the Twisted reactor loop
    reactor.run()
示例#20
0
def check_web_path_service_websocket(config):
   """
   Check a "websocket" path service on Web transport.

   :param config: The path service configuration.
   :type config: dict
   """
   if 'options' in config:
      check_websocket_options(config['options'])

   if 'debug' in config:
      debug = config['debug']
      if type(debug) != bool:
         raise Exception("'debug' in WebSocket configuration must be boolean ({} encountered)".format(type(debug)))

   if 'url' in config:
      url = config['url']
      if type(url) != six.text_type:
         raise Exception("'url' in WebSocket configuration must be str ({} encountered)".format(type(url)))
      try:
         u = parseWsUrl(url)
      except Exception as e:
         raise Exception("invalid 'url' in WebSocket configuration : {}".format(e))
示例#21
0
文件: wamp.py 项目: goks/Winky
    def run(self, make, start_reactor=True):
        """
        Run the application component.

        :param make: A factory that produces instances of :class:`autobahn.asyncio.wamp.ApplicationSession`
           when called with an instance of :class:`autobahn.wamp.types.ComponentConfig`.
        :type make: callable

        :param start_reactor: if True (the default) this method starts
           the Twisted reactor and doesn't return until the reactor
           stops. If there are any problems starting the reactor or
           connect()-ing, we stop the reactor and raise the exception
           back to the caller.

        :returns: None is returned, unless you specify
            ``start_reactor=False`` in which case the Deferred that
            connect() returns is returned; this will callback() with
            an IProtocol instance, which will actually be an instance
            of :class:`WampWebSocketClientProtocol`
        """
        if start_reactor:
            # only select framework, set loop and start logging when we are asked
            # start the reactor - otherwise we are running in a program that likely
            # already tool care of all this.
            from twisted.internet import reactor
            txaio.use_twisted()
            txaio.config.loop = reactor

            if self.debug or self.debug_app:
                txaio.start_logging(level='debug')
            else:
                txaio.start_logging(level='info')

        isSecure, host, port, resource, path, params = parseWsUrl(self.url)

        # factory for use ApplicationSession
        def create():
            cfg = ComponentConfig(self.realm, self.extra)
            try:
                session = make(cfg)
            except Exception as e:
                if start_reactor:
                    # the app component could not be created .. fatal
                    self.log.error(str(e))
                    reactor.stop()
                else:
                    # if we didn't start the reactor, it's up to the
                    # caller to deal with errors
                    raise
            else:
                session.debug_app = self.debug_app
                return session

        # create a WAMP-over-WebSocket transport client factory
        transport_factory = WampWebSocketClientFactory(create, url=self.url, serializers=self.serializers,
                                                       proxy=self.proxy, debug=self.debug)

        # supress pointless log noise like
        # "Starting factory <autobahn.twisted.websocket.WampWebSocketClientFactory object at 0x2b737b480e10>""
        transport_factory.noisy = False

        # if user passed ssl= but isn't using isSecure, we'll never
        # use the ssl argument which makes no sense.
        context_factory = None
        if self.ssl is not None:
            if not isSecure:
                raise RuntimeError(
                    'ssl= argument value passed to %s conflicts with the "ws:" '
                    'prefix of the url argument. Did you mean to use "wss:"?' %
                    self.__class__.__name__)
            context_factory = self.ssl
        elif isSecure:
            from twisted.internet.ssl import optionsForClientTLS
            context_factory = optionsForClientTLS(host)

        from twisted.internet import reactor
        if self.proxy is not None:
            from twisted.internet.endpoints import TCP4ClientEndpoint
            client = TCP4ClientEndpoint(reactor, self.proxy['host'], self.proxy['port'])
            transport_factory.contextFactory = context_factory
        elif isSecure:
            from twisted.internet.endpoints import SSL4ClientEndpoint
            assert context_factory is not None
            client = SSL4ClientEndpoint(reactor, host, port, context_factory)
        else:
            from twisted.internet.endpoints import TCP4ClientEndpoint
            client = TCP4ClientEndpoint(reactor, host, port)

        d = client.connect(transport_factory)

        # as the reactor shuts down, we wish to wait until we've sent
        # out our "Goodbye" message; leave() returns a Deferred that
        # fires when the transport gets to STATE_CLOSED
        def cleanup(proto):
            if hasattr(proto, '_session') and proto._session is not None:
                if proto._session.is_attached():
                    return proto._session.leave()
                elif proto._session.is_connected():
                    return proto._session.disconnect()

        # when our proto was created and connected, make sure it's cleaned
        # up properly later on when the reactor shuts down for whatever reason
        def init_proto(proto):
            reactor.addSystemEventTrigger('before', 'shutdown', cleanup, proto)
            return proto

        # if we connect successfully, the arg is a WampWebSocketClientProtocol
        d.addCallback(init_proto)

        # if the user didn't ask us to start the reactor, then they
        # get to deal with any connect errors themselves.
        if start_reactor:
            # if an error happens in the connect(), we save the underlying
            # exception so that after the event-loop exits we can re-raise
            # it to the caller.

            class ErrorCollector(object):
                exception = None

                def __call__(self, failure):
                    self.exception = failure.value
                    reactor.stop()
            connect_error = ErrorCollector()
            d.addErrback(connect_error)

            # now enter the Twisted reactor loop
            reactor.run()

            # if we exited due to a connection error, raise that to the
            # caller
            if connect_error.exception:
                raise connect_error.exception

        else:
            # let the caller handle any errors
            return d
示例#22
0
    def run(self, make, start_reactor=True):
        """
        Run the application component.

        :param make: A factory that produces instances of :class:`autobahn.asyncio.wamp.ApplicationSession`
           when called with an instance of :class:`autobahn.wamp.types.ComponentConfig`.
        :type make: callable

        :param start_reactor: if True (the default) this method starts
           the Twisted reactor and doesn't return until the reactor
           stops. If there are any problems starting the reactor or
           connect()-ing, we stop the reactor and raise the exception
           back to the caller.

        :returns: None is returned, unless you specify
            ``start_reactor=False`` in which case the Deferred that
            connect() returns is returned; this will callback() with
            an IProtocol instance, which will actually be an instance
            of :class:`WampWebSocketClientProtocol`
        """
        from twisted.internet import reactor

        isSecure, host, port, resource, path, params = parseWsUrl(self.url)

        # start logging to console
        if self.debug or self.debug_wamp or self.debug_app:
            log.startLogging(sys.stdout)

        # factory for use ApplicationSession
        def create():
            cfg = ComponentConfig(self.realm, self.extra)
            try:
                session = make(cfg)
            except Exception as e:
                if start_reactor:
                    # the app component could not be created .. fatal
                    log.err(str(e))
                    reactor.stop()
                else:
                    # if we didn't start the reactor, it's up to the
                    # caller to deal with errors
                    raise
            else:
                session.debug_app = self.debug_app
                return session

        # create a WAMP-over-WebSocket transport client factory
        transport_factory = WampWebSocketClientFactory(create, url=self.url,
                                                       debug=self.debug, debug_wamp=self.debug_wamp)

        # start the client from a Twisted endpoint
        from twisted.internet.endpoints import clientFromString

        if isSecure:
            endpoint_descriptor = "ssl:{0}:{1}".format(host, port)
        else:
            endpoint_descriptor = "tcp:{0}:{1}".format(host, port)

        client = clientFromString(reactor, endpoint_descriptor)
        d = client.connect(transport_factory)

        # if the user didn't ask us to start the reactor, then they
        # get to deal with any connect errors themselves.
        if start_reactor:
            # if an error happens in the connect(), we save the underlying
            # exception so that after the event-loop exits we can re-raise
            # it to the caller.

            class ErrorCollector:
                exception = None

                def __call__(self, failure):
                    self.exception = failure.value
                    # print(failure.getErrorMessage())
                    reactor.stop()
            connect_error = ErrorCollector()
            d.addErrback(connect_error)

            # now enter the Twisted reactor loop
            reactor.run()

            # if we exited due to a connection error, raise that to the
            # caller
            if connect_error.exception:
                raise connect_error.exception

        else:
            # let the caller handle any errors
            return d
示例#23
0
 def test_parse_url06(self):
    self.assertEqual(parseWsUrl("wss://localhost/ws?foo=bar"), (True, 'localhost', 443, '/ws?foo=bar', '/ws', {'foo': ['bar']}))
示例#24
0
 def test_parse_url05(self):
    self.assertEqual(parseWsUrl("wss://localhost/ws"), (True, 'localhost', 443, '/ws', '/ws', {}))
示例#25
0
 def test_parse_url04(self):
    self.assertEqual(parseWsUrl("wss://localhost:443"), (True, 'localhost', 443, '/', '/', {}))
示例#26
0
    def run(self, make, start_reactor=True):
        """
        Run the application component.

        :param make: A factory that produces instances of :class:`autobahn.asyncio.wamp.ApplicationSession`
           when called with an instance of :class:`autobahn.wamp.types.ComponentConfig`.
        :type make: callable

        :param start_reactor: if True (the default) this method starts
           the Twisted reactor and doesn't return until the reactor
           stops. If there are any problems starting the reactor or
           connect()-ing, we stop the reactor and raise the exception
           back to the caller.

        :returns: None is returned, unless you specify
            ``start_reactor=False`` in which case the Deferred that
            connect() returns is returned; this will callback() with
            an IProtocol instance, which will actually be an instance
            of :class:`WampWebSocketClientProtocol`
        """
        from twisted.internet import reactor
        txaio.use_twisted()
        txaio.config.loop = reactor

        isSecure, host, port, resource, path, params = parseWsUrl(self.url)

        # start logging to console
        if self.debug or self.debug_wamp or self.debug_app:
            log.startLogging(sys.stdout)

        # factory for use ApplicationSession
        def create():
            cfg = ComponentConfig(self.realm, self.extra)
            try:
                session = make(cfg)
            except Exception as e:
                if start_reactor:
                    # the app component could not be created .. fatal
                    log.err(str(e))
                    reactor.stop()
                else:
                    # if we didn't start the reactor, it's up to the
                    # caller to deal with errors
                    raise
            else:
                session.debug_app = self.debug_app
                return session

        # create a WAMP-over-WebSocket transport client factory
        transport_factory = WampWebSocketClientFactory(
            create, url=self.url, debug=self.debug, debug_wamp=self.debug_wamp)

        # start the client from a Twisted endpoint
        from twisted.internet.endpoints import clientFromString

        if isSecure:
            endpoint_descriptor = "ssl:{0}:{1}".format(host, port)
        else:
            endpoint_descriptor = "tcp:{0}:{1}".format(host, port)

        client = clientFromString(reactor, endpoint_descriptor)
        d = client.connect(transport_factory)

        # if the user didn't ask us to start the reactor, then they
        # get to deal with any connect errors themselves.
        if start_reactor:
            # if an error happens in the connect(), we save the underlying
            # exception so that after the event-loop exits we can re-raise
            # it to the caller.

            class ErrorCollector(object):
                exception = None

                def __call__(self, failure):
                    self.exception = failure.value
                    # print(failure.getErrorMessage())
                    reactor.stop()

            connect_error = ErrorCollector()
            d.addErrback(connect_error)

            # now enter the Twisted reactor loop
            reactor.run()

            # if we exited due to a connection error, raise that to the
            # caller
            if connect_error.exception:
                raise connect_error.exception

        else:
            # let the caller handle any errors
            return d
示例#27
0
 def test_parse_url08(self):
    self.assertEqual(parseWsUrl("wss://localhost/ws?foo=bar&moo=23&moo=44"), (True, 'localhost', 443, '/ws?foo=bar&moo=23&moo=44', '/ws', {'moo': ['23', '44'], 'foo': ['bar']}))
示例#28
0
        # print "reason:", reason
        ReconnectingClientFactory.clientConnectionFailed(
            self, connector, reason)

    def clientConnectionLost(self, connector, reason):
        print("Connection Lost")
        # print "reason:", reason
        ReconnectingClientFactory.clientConnectionLost(self, connector, reason)


if __name__ == '__main__':
    Component.init()

    # 1) create a WAMP application session factory
    component_config = types.ComponentConfig(realm=Component.config["realm"])
    session_factory = wamp.ApplicationSessionFactory(config=component_config)
    session_factory.session = Component

    # 2) create a WAMP-over-WebSocket transport client factory
    url = Component.config["url"]
    transport_factory = MyClientFactory(session_factory, url=url, debug=False)

    # 3) start the client from a Twisted endpoint
    isSecure, host, port, resource, path, params = parseWsUrl(url)
    transport_factory.host = host
    transport_factory.port = port
    websocket.connectWS(transport_factory)

    # 4) now enter the Twisted reactor loop
    reactor.run()
示例#29
0
    def run(self, make, start_reactor=True):
        """
        Run the application component.

        :param make: A factory that produces instances of :class:`autobahn.asyncio.wamp.ApplicationSession`
           when called with an instance of :class:`autobahn.wamp.types.ComponentConfig`.
        :type make: callable

        :param start_reactor: if True (the default) this method starts
           the Twisted reactor and doesn't return until the reactor
           stops. If there are any problems starting the reactor or
           connect()-ing, we stop the reactor and raise the exception
           back to the caller.

        :returns: None is returned, unless you specify
            ``start_reactor=False`` in which case the Deferred that
            connect() returns is returned; this will callback() with
            an IProtocol instance, which will actually be an instance
            of :class:`WampWebSocketClientProtocol`
        """
        from twisted.internet import reactor
        txaio.use_twisted()
        txaio.config.loop = reactor

        isSecure, host, port, resource, path, params = parseWsUrl(self.url)

        # start logging to console
        if self.debug or self.debug_wamp or self.debug_app:
            log.startLogging(sys.stdout)

        # factory for use ApplicationSession
        def create():
            cfg = ComponentConfig(self.realm, self.extra)
            try:
                session = make(cfg)
            except Exception as e:
                if start_reactor:
                    # the app component could not be created .. fatal
                    log.err(str(e))
                    reactor.stop()
                else:
                    # if we didn't start the reactor, it's up to the
                    # caller to deal with errors
                    raise
            else:
                session.debug_app = self.debug_app
                return session

        # create a WAMP-over-WebSocket transport client factory
        transport_factory = WampWebSocketClientFactory(create, url=self.url,
                                                       debug=self.debug, debug_wamp=self.debug_wamp)

        # if user passed ssl= but isn't using isSecure, we'll never
        # use the ssl argument which makes no sense.
        context_factory = None
        if self.ssl is not None:
            if not isSecure:
                raise RuntimeError(
                    'ssl= argument value passed to %s conflicts with the "ws:" '
                    'prefix of the url argument. Did you mean to use "wss:"?' %
                    self.__class__.__name__)
            context_factory = self.ssl
        elif isSecure:
            from twisted.internet.ssl import optionsForClientTLS
            context_factory = optionsForClientTLS(six.u(host))

        if isSecure:
            from twisted.internet.endpoints import SSL4ClientEndpoint
            assert context_factory is not None
            client = SSL4ClientEndpoint(reactor, host, port, context_factory)
        else:
            from twisted.internet.endpoints import TCP4ClientEndpoint
            client = TCP4ClientEndpoint(reactor, host, port)

        d = client.connect(transport_factory)

        # as the reactor shuts down, we wish to wait until we've sent
        # out our "Goodbye" message; leave() returns a Deferred that
        # fires when the transport gets to STATE_CLOSED
        def cleanup(proto):
            if hasattr(proto, '_session') and proto._session is not None:
                return proto._session.leave()
        # if we connect successfully, the arg is a WampWebSocketClientProtocol
        d.addCallback(lambda proto: reactor.addSystemEventTrigger(
            'before', 'shutdown', cleanup, proto))

        # if the user didn't ask us to start the reactor, then they
        # get to deal with any connect errors themselves.
        if start_reactor:
            # if an error happens in the connect(), we save the underlying
            # exception so that after the event-loop exits we can re-raise
            # it to the caller.

            class ErrorCollector(object):
                exception = None

                def __call__(self, failure):
                    self.exception = failure.value
                    # print(failure.getErrorMessage())
                    reactor.stop()
            connect_error = ErrorCollector()
            d.addErrback(connect_error)

            # now enter the Twisted reactor loop
            reactor.run()

            # if we exited due to a connection error, raise that to the
            # caller
            if connect_error.exception:
                raise connect_error.exception

        else:
            # let the caller handle any errors
            return d
示例#30
0
    def run(self, make, start_reactor=True):
        """
        Run the application component.

        :param make: A factory that produces instances of :class:`autobahn.asyncio.wamp.ApplicationSession`
           when called with an instance of :class:`autobahn.wamp.types.ComponentConfig`.
        :type make: callable

        :param start_reactor: if True (the default) this method starts
           the Twisted reactor and doesn't return until the reactor
           stops. If there are any problems starting the reactor or
           connect()-ing, we stop the reactor and raise the exception
           back to the caller.

        :returns: None is returned, unless you specify
            ``start_reactor=False`` in which case the Deferred that
            connect() returns is returned; this will callback() with
            an IProtocol instance, which will actually be an instance
            of :class:`WampWebSocketClientProtocol`
        """
        from twisted.internet import reactor
        txaio.use_twisted()
        txaio.config.loop = reactor

        isSecure, host, port, resource, path, params = parseWsUrl(self.url)

        # start logging to console
        if self.debug or self.debug_wamp or self.debug_app:
            log.startLogging(sys.stdout)

        # factory for use ApplicationSession
        def create():
            cfg = ComponentConfig(self.realm, self.extra)
            try:
                session = make(cfg)
            except Exception as e:
                if start_reactor:
                    # the app component could not be created .. fatal
                    log.err(str(e))
                    reactor.stop()
                else:
                    # if we didn't start the reactor, it's up to the
                    # caller to deal with errors
                    raise
            else:
                session.debug_app = self.debug_app
                return session

        # create a WAMP-over-WebSocket transport client factory
        transport_factory = WampWebSocketClientFactory(
            create,
            url=self.url,
            serializers=self.serializers,
            debug=self.debug,
            debug_wamp=self.debug_wamp)

        # if user passed ssl= but isn't using isSecure, we'll never
        # use the ssl argument which makes no sense.
        context_factory = None
        if self.ssl is not None:
            if not isSecure:
                raise RuntimeError(
                    'ssl= argument value passed to %s conflicts with the "ws:" '
                    'prefix of the url argument. Did you mean to use "wss:"?' %
                    self.__class__.__name__)
            context_factory = self.ssl
        elif isSecure:
            from twisted.internet.ssl import optionsForClientTLS
            context_factory = optionsForClientTLS(host)

        if isSecure:
            from twisted.internet.endpoints import SSL4ClientEndpoint
            assert context_factory is not None
            client = SSL4ClientEndpoint(reactor, host, port, context_factory)
        else:
            from twisted.internet.endpoints import TCP4ClientEndpoint
            client = TCP4ClientEndpoint(reactor, host, port)

        d = client.connect(transport_factory)

        # as the reactor shuts down, we wish to wait until we've sent
        # out our "Goodbye" message; leave() returns a Deferred that
        # fires when the transport gets to STATE_CLOSED
        def cleanup(proto):
            if hasattr(proto, '_session') and proto._session is not None:
                return proto._session.leave()

        # when our proto was created and connected, make sure it's cleaned
        # up properly later on when the reactor shuts down for whatever reason
        def init_proto(proto):
            reactor.addSystemEventTrigger('before', 'shutdown', cleanup, proto)
            return proto

        # if we connect successfully, the arg is a WampWebSocketClientProtocol
        d.addCallback(init_proto)

        # if the user didn't ask us to start the reactor, then they
        # get to deal with any connect errors themselves.
        if start_reactor:
            # if an error happens in the connect(), we save the underlying
            # exception so that after the event-loop exits we can re-raise
            # it to the caller.

            class ErrorCollector(object):
                exception = None

                def __call__(self, failure):
                    self.exception = failure.value
                    # print(failure.getErrorMessage())
                    reactor.stop()

            connect_error = ErrorCollector()
            d.addErrback(connect_error)

            # now enter the Twisted reactor loop
            reactor.run()

            # if we exited due to a connection error, raise that to the
            # caller
            if connect_error.exception:
                raise connect_error.exception

        else:
            # let the caller handle any errors
            return d
示例#31
0
        '--cpuid',
        dest='cpuid',
        type=int,
        default=None,
        help=
        'If given, this is a worker which will use provided CPU core to set its affinity.'
    )

    options = parser.parse_args()

    if options.profile and not hasStatprof:
        raise Exception("profiling requested, but statprof not installed")

    # parse WS URI into components and forward via options
    # FIXME: add TLS support
    isSecure, host, wsport, resource, path, params = parseWsUrl(options.wsuri)
    options.wsport = wsport

    # if not options.silence:
    #   log.startLogging(sys.stdout)

    if options.fd is not None:
        # run worker
        worker(options)
    else:
        if not options.silence:
            for m in startupMsgs:
                print m
        # run master
        master(options)
示例#32
0
    parser.add_argument('--silence', dest='silence', action="store_true", default=False, help='Silence log output.')
    parser.add_argument('--debug', dest='debug', action="store_true", default=False, help='Enable WebSocket debug output.')
    parser.add_argument('--interval', dest='interval', type=int, default=5, help='Worker stats update interval.')
    parser.add_argument('--profile', dest='profile', action="store_true", default=False, help='Enable profiling.')

    parser.add_argument('--fd', dest='fd', type=int, default=None, help='If given, this is a worker which will use provided FD and all other options are ignored.')
    parser.add_argument('--cpuid', dest='cpuid', type=int, default=None, help='If given, this is a worker which will use provided CPU core to set its affinity.')

    options = parser.parse_args()

    if options.profile and not hasStatprof:
        raise Exception("profiling requested, but statprof not installed")

    # parse WS URI into components and forward via options
    # FIXME: add TLS support
    isSecure, host, wsport, resource, path, params = parseWsUrl(options.wsuri)
    options.wsport = wsport

    # if not options.silence:
    #   log.startLogging(sys.stdout)

    if options.fd is not None:
        # run worker
        worker(options)
    else:
        if not options.silence:
            for m in startupMsgs:
                print m
        # run master
        master(options)
示例#33
0
 def test_parse_url02(self):
    self.assertEqual(parseWsUrl("ws://localhost:80"), (False, 'localhost', 80, '/', '/', {}))
示例#34
0
    def __init__(self, main=None, setup=None, transports=None, config=None):
        """

        :param main: A callable that runs user code for the component. The component will be
            started with a "main-like" procedure. When a transport has been connected and
            a session has been established and joined a realm, the user code will be run until it finishes
            which signals that the component has run to completion.
        :type main: callable
        :param setup: A callable that runs user code for the component. The component will be
            started with a "setup-like" procedure. When a transport has been connected and
            a session has been established and joined a realm, the user code will be run until it finishes
            which signals that the component is now "ready". The component will continue to run until
            it explicitly closes the session or the underlying transport closes.
        :type setup: callable
        :param transports: Transport configurations for creating transports.
        :type transports: None or unicode or list
        :param config: Session configuration.
        :type config: None or dict
        """
        ObservableMixin.__init__(self)

        if main is None and setup is None:
            raise RuntimeError('either a "main" or "setup" procedure must be provided for a component')

        if main is not None and setup is not None:
            raise RuntimeError('either a "main" or "setup" procedure must be provided for a component (not both)')

        if main is not None and not callable(main):
            raise RuntimeError('"main" must be a callable if given')

        if setup is not None and not callable(setup):
            raise RuntimeError('"setup" must be a callable if given')

        if setup:
            self._entry = setup
            self._entry_type = Component.TYPE_SETUP
        elif main:
            self._entry = main
            self._entry_type = Component.TYPE_MAIN
        else:
            assert(False), 'logic error'

        # use WAMP-over-WebSocket to localhost when no transport is specified at all
        if transports is None:
            transports = u'ws://127.0.0.1:8080/ws'

        # allows to provide an URL instead of a list of transports
        if type(transports) == six.text_type:
            url = transports
            is_secure, host, port, resource, path, params = parseWsUrl(url)
            transport = {
                'type': 'websocket',
                'url': url,
                'endpoint': {
                    'type': 'tcp',
                    'host': host,
                    'port': port
                }
            }
            if is_secure:
                # FIXME
                transport['endpoint']['tls'] = {}
            transports = [transport]

        # now check and save list of transports
        self._transports = []
        idx = 0
        for transport in transports:
            check_transport(transport)
            self._transports.append(Transport(idx, transport))
            idx += 1

        self._realm = u'realm1'
        self._extra = None
示例#35
0
 def test_parse_url06(self):
     self.assertEqual(parseWsUrl("wss://localhost/ws?foo=bar"),
                      (True, 'localhost', 443, '/ws?foo=bar', '/ws', {
                          'foo': ['bar']
                      }))
示例#36
0
   def run(self, make, start_reactor = True):
      """
      Run the application component.

      :param make: A factory that produces instances of :class:`autobahn.asyncio.wamp.ApplicationSession`
         when called with an instance of :class:`autobahn.wamp.types.ComponentConfig`.
      :type make: callable
      """
      from twisted.internet import reactor

      isSecure, host, port, resource, path, params = parseWsUrl(self.url)

      ## start logging to console
      if self.debug or self.debug_wamp or self.debug_app:
         log.startLogging(sys.stdout)

      ## run an embedded router if ask to start standalone
      if self.standalone:

         from twisted.internet.endpoints import serverFromString

         router_factory = RouterFactory()
         session_factory = RouterSessionFactory(router_factory)

         transport_factory = WampWebSocketServerFactory(session_factory, debug = self.debug, debug_wamp = self.debug_wamp)
         transport_factory.setProtocolOptions(failByDrop = False)

         server = serverFromString(reactor, "tcp:{0}".format(port))
         server.listen(transport_factory)

      ## factory for use ApplicationSession
      def create():
         cfg = ComponentConfig(self.realm, self.extra)
         try:
            session = make(cfg)
         except Exception:
            ## the app component could not be created .. fatal
            log.err()
            reactor.stop()
         else:
            session.debug_app = self.debug_app
            return session

      ## create a WAMP-over-WebSocket transport client factory
      transport_factory = WampWebSocketClientFactory(create, url = self.url, serializers = self.serializers,
         debug = self.debug, debug_wamp = self.debug_wamp)

      ## start the client from a Twisted endpoint
      from twisted.internet.endpoints import clientFromString

      if isSecure:
         endpoint_descriptor = "ssl:{0}:{1}".format(host, port)
      else:
         endpoint_descriptor = "tcp:{0}:{1}".format(host, port)

      client = clientFromString(reactor, endpoint_descriptor)
      client.connect(transport_factory)

      ## now enter the Twisted reactor loop
      if start_reactor:
         reactor.run()
示例#37
0
    def run(self, make):
        """
        Run the application component.

        :param make: A factory that produces instances of :class:`autobahn.asyncio.wamp.ApplicationSession`
           when called with an instance of :class:`autobahn.wamp.types.ComponentConfig`.
        :type make: callable
        """

        # 1) factory for use ApplicationSession
        def create():
            cfg = ComponentConfig(self.realm, self.extra)
            try:
                session = make(cfg)
            except Exception as e:
                # the app component could not be created .. fatal
                print(e)
                asyncio.get_event_loop().stop()
            else:
                session.debug_app = self.debug_app
                return session

        isSecure, host, port, resource, path, params = parseWsUrl(self.url)

        if self.ssl is None:
            ssl = isSecure
        else:
            if self.ssl and not isSecure:
                raise RuntimeError(
                    'ssl argument value passed to %s conflicts with the "ws:" '
                    'prefix of the url argument. Did you mean to use "wss:"?' %
                    self.__class__.__name__)
            ssl = self.ssl

        # 2) create a WAMP-over-WebSocket transport client factory
        transport_factory = WampWebSocketClientFactory(
            create,
            url=self.url,
            serializers=self.serializers,
            debug=self.debug,
            debug_wamp=self.debug_wamp)

        # 3) start the client
        loop = asyncio.get_event_loop()
        txaio.use_asyncio()
        txaio.config.loop = loop
        coro = loop.create_connection(transport_factory, host, port, ssl=ssl)
        (transport, protocol) = loop.run_until_complete(coro)

        try:
            loop.add_signal_handler(signal.SIGTERM, loop.stop)
        except NotImplementedError:
            # signals are not available on Windows
            pass

        # 4) now enter the asyncio event loop
        try:
            loop.run_forever()
        except KeyboardInterrupt:
            # wait until we send Goodbye if user hit ctrl-c
            # (done outside this except so SIGTERM gets the same handling)
            pass

        # give Goodbye message a chance to go through, if we still
        # have an active session
        if protocol._session:
            loop.run_until_complete(protocol._session.leave())

        loop.close()