def receive(self): while True: frame = self._parser.get() if frame is not None: return frame try: data = self._socket.recv(self.READ_SIZE) if not data: raise StompConnectionError('No more data') except (IOError, StompConnectionError) as e: self.disconnect() raise StompConnectionError('Connection closed [%s]' % e) self._parser.add(data)
def disconnect(self): try: self._socket and self._socket.close() except IOError as e: raise StompConnectionError('Could not close connection cleanly [%s]' % e) finally: self._socket = None
def connect(self, headers=None, versions=None, host=None, heartBeats=None, connectTimeout=None, connectedTimeout=None): """Establish a connection to a STOMP broker. If the wire-level connect fails, attempt a failover according to the settings in the client's :class:`~.StompConfig` object. If there are active subscriptions in the :attr:`~.sync.client.Stomp.session`, replay them when the STOMP connection is established. :param versions: The STOMP protocol versions we wish to support. The default behavior (:obj:`None`) is the same as for the :func:`~.commands.connect` function of the commands API, but the highest supported version will be the one you specified in the :class:`~.StompConfig` object. The version which is valid for the connection about to be initiated will be stored in the :attr:`~.sync.client.Stomp.session`. :param connectTimeout: This is the time (in seconds) to wait for the wire-level connection to be established. If :obj:`None`, we will wait indefinitely. :param connectedTimeout: This is the time (in seconds) to wait for the STOMP connection to be established (that is, the broker's **CONNECTED** frame to arrive). If :obj:`None`, we will wait indefinitely. **Example:** >>> client = Stomp(StompConfig('tcp://localhost:61613', version=StompSpec.VERSION_1_1)) >>> client.connect() >>> client.session.version '1.1' >>> client.disconnect() >>> client.connect(versions=[StompSpec.VERSION_1_0]) >>> client.session.version '1.0' >>> client.disconnect() >>> client.session.version '1.1' .. seealso :: The :mod:`.protocol.failover` and :mod:`.protocol.session` modules for the details of subscription replay and failover transport. """ try: # preserve existing connection self._transport except StompConnectionError: pass else: raise StompConnectionError('Already connected to %s' % self._transport) try: for (broker, connectDelay) in self._failover: transport = self._transportFactory(broker['host'], broker['port']) if connectDelay: self.log.debug('Delaying connect attempt for %d ms' % int(connectDelay * 1000)) time.sleep(connectDelay) self.log.info('Connecting to %s ...' % transport) try: transport.connect(connectTimeout) except StompConnectionError as e: self.log.warning('Could not connect to %s [%s]' % (transport, e)) else: self.log.info('Connection established') self._transport = transport self._connect(headers, versions, host, heartBeats, connectedTimeout) break except StompConnectionError as e: self.log.error('Reconnect failed [%s]' % e) raise
def _protocol(self): try: protocol = self.__protocol except AttributeError: self._protocol = None return self._protocol if not protocol: raise StompConnectionError('Not connected') return protocol
def connect(self, timeout=None): kwargs = {} if (timeout is None) else {'timeout': timeout} try: self._socket = socket.create_connection((self.host, self.port), **kwargs) except IOError as e: raise StompConnectionError('Could not establish connection [%s]' % e) self._parser.reset()
def connect(self, timeout=None): """ Allow older versions of ssl module, allow http proxy connections """ LOG.debug("stomp_transport.connect()") ssl_params = None if isinstance(self.sslContext, dict): # This is actually a dictionary of ssl parameters for wrapping the socket ssl_params = self.sslContext self.sslContext = None try: if self.proxy_host: try: # Don't try to import this unless we need it import socks except ImportError: raise ImportError( "No http proxy support available. Is pysocks installed?" ) LOG.info("Connecting through proxy %s", self.proxy_host) self._socket = socks.socksocket() self._socket.set_proxy(socks.HTTP, self.proxy_host, self.proxy_port, True, username=self.proxy_user, password=self.proxy_password) else: self._socket = socket.socket() self._socket.settimeout(timeout) self._socket.connect((self.host, self.port)) if ssl_params: # For cases where we don't have a modern SSLContext (so no SNI) cert_required = ssl.CERT_REQUIRED if ssl_params[ "ca_certs"] else ssl.CERT_NONE self._socket = ssl.wrap_socket( self._socket, keyfile=ssl_params['key_file'], certfile=ssl_params['cert_file'], cert_reqs=cert_required, ca_certs=ssl_params['ca_certs'], ssl_version=ssl_params['ssl_version']) if cert_required: LOG.info("Performing manual hostname check") cert = self._socket.getpeercert() self.match_hostname(cert, self.host) if self.sslContext: self._socket = self.sslContext.wrap_socket( self._socket, server_hostname=self.host) except IOError as e: raise StompConnectionError('Could not establish connection [%s]' % e) self._parser.reset()
def _transport(self): transport = self.__transport if not transport: raise StompConnectionError('Not connected') try: transport.canRead(0) except Exception as e: self.close(flush=False) raise e return transport
def connect(self, timeout=None): try: self._socket = socket.socket() self._socket.settimeout(timeout) if self.sslContext: self._socket = self.sslContext.wrap_socket(self._socket, server_hostname=self.host) self._socket.connect((self.host, self.port)) except IOError as e: raise StompConnectionError('Could not establish connection [%s]' % e) self._parser.reset()
def connect(self, timeout=None): kwargs = {} if (timeout is None) else {'timeout': timeout} try: self._socket = socket.create_connection((self.host, self.port), **kwargs) if self.protocol == Broker.PROTOCOL_SSL: self._socket = sslWrapSocket(self._socket, sslContext=self.sslContext, host=self.host) except IOError as e: raise StompConnectionError('Could not establish connection [%s]' % e) self._parser.reset()
def connect(self, headers=None, versions=None, host=None, heartBeats=None, connectTimeout=None, connectedTimeout=None): """connect(headers=None, versions=None, host=None, heartBeats=None, connectTimeout=None, connectedTimeout=None) Establish a connection to a STOMP broker. If the wire-level connect fails, attempt a failover according to the settings in the client's :class:`~.StompConfig` object. If there are active subscriptions in the :attr:`~.async.client.Stomp.session`, replay them when the STOMP connection is established. This method returns a :class:`twisted.internet.defer.Deferred` object which calls back with :obj:`self` when the STOMP connection has been established and all subscriptions (if any) were replayed. In case of an error, it will err back with the reason of the failure. :param versions: The STOMP protocol versions we wish to support. The default behavior (:obj:`None`) is the same as for the :func:`~.commands.connect` function of the commands API, but the highest supported version will be the one you specified in the :class:`~.StompConfig` object. The version which is valid for the connection about to be initiated will be stored in the :attr:`~.async.client.Stomp.session`. :param connectTimeout: This is the time (in seconds) to wait for the wire-level connection to be established. If :obj:`None`, we will wait indefinitely. :param connectedTimeout: This is the time (in seconds) to wait for the STOMP connection to be established (that is, the broker's **CONNECTED** frame to arrive). If :obj:`None`, we will wait indefinitely. .. note :: Only one connect attempt may be pending at a time. Any other attempt will result in a :class:`~.StompAlreadyRunningError`. .. seealso :: The :mod:`.protocol.failover` and :mod:`~.protocol.session` modules for the details of subscription replay and failover transport. """ frame = self.session.connect(self._config.login, self._config.passcode, headers, versions, host, heartBeats) try: self._protocol except: pass else: raise StompConnectionError('Already connected') for listener in self._listenersFactory(): self.add(listener) try: self._protocol = yield self._protocolCreator.connect( connectTimeout, self._onFrame, self._onConnectionLost) except Exception as e: self.log.error('Endpoint connect failed') raise try: self.sendFrame(frame) yield self._notify( lambda l: l.onConnect(self, frame, connectedTimeout)) except Exception as e: self.disconnect(failure=e) yield self.disconnected yield self._replay() defer.returnValue(self)
def disconnect(self): try: self._poll and self._socket and self._poll.unregister(self._socket) except: pass finally: self._poll = None try: self._socket and self._socket.close() except IOError as e: raise StompConnectionError( 'Could not close connection cleanly [%s]' % e) finally: self._socket = None
def onConnectionLost(self, connection, reason): self.log.info('Disconnected: %s' % reason.getErrorMessage()) if not self._disconnecting: self._disconnectReason = StompConnectionError('Unexpected connection loss [%s]' % reason.getErrorMessage()) connection.remove(self) connection.session.close(flush=not self._disconnectReason) if self._disconnectReason: if self.log.isEnabledFor(logging.DEBUG): self.log.debug('Calling disconnected errback: %s' % self._disconnectReason) connection.disconnected.errback(self._disconnectReason) else: if self.log.isEnabledFor(logging.DEBUG): self.log.debug('Calling disconnected callback') connection.disconnected.callback(None)
def connect(self, headers=None, versions=None, host=None, heartBeats=None, connectTimeout=None, connectedTimeout=None): """connect(headers=None, versions=None, host=None, heartBeats=None, connectTimeout=None, connectedTimeout=None) Establish a connection to a STOMP broker. If the wire-level connect fails, attempt a failover according to the settings in the client's :class:`~.StompConfig` object. If there are active subscriptions in the :attr:`~.twisted.client.Stomp.session`, replay them when the STOMP connection is established. :param versions: The STOMP protocol versions we wish to support. The default behavior (:obj:`None`) is the same as for the :func:`~.commands.connect` function of the commands API, but the highest supported version will be the one you specified in the :class:`~.StompConfig` object. The version which is valid for the connection about to be initiated will be stored in the :attr:`~.twisted.client.Stomp.session`. :param connectTimeout: This is the time (in seconds) to wait for the wire-level connection to be established. If :obj:`None`, we will wait indefinitely. :param connectedTimeout: This is the time (in seconds) to wait for the STOMP connection to be established (that is, the broker's **CONNECTED** frame to arrive). If :obj:`None`, we will wait indefinitely. .. seealso :: The :mod:`.protocol.failover` and :mod:`~.protocol.session` modules for the details of subscription replay and failover transport. """ try: self._protocol except: pass else: raise StompConnectionError('Already connected') for listener in self._listenersFactory(): self.add(listener) try: self._protocol = yield self._protocolCreator.connect( connectTimeout, self._onFrame, self._onConnectionLost) except: self._onConnectionLost(failure.Failure()) yield self.disconnected try: frame = self.session.connect(self._config.login, self._config.passcode, headers, versions, host, heartBeats) self.sendFrame(frame) yield self._notify( lambda l: l.onConnect(self, frame, connectedTimeout)) except Exception as e: self.disconnect(reason=e) yield self.disconnected yield self._replay()
def _beat(self, connection, which): try: self._heartBeats.pop(which).cancel() except: pass if not connection: return remaining = self._beatRemaining(connection.session, which) if remaining < 0: return if not remaining: if which == 'client': connection.sendFrame(connection.session.beat()) remaining = self._beatRemaining(connection.session, which) else: connection.disconnect(reason=StompConnectionError('Server heart-beat timeout')) return self._heartBeats[which] = reactor.callLater(remaining, self._beat, connection, which) # @UndefinedVariable
def _check(self): if not self._connected(): raise StompConnectionError('Not connected')
def _write(self, data): self._check() try: self._socket.sendall(data) except IOError as e: raise StompConnectionError('Could not send to connection [%s]' % e)
def onConnectionLost(self, connection, reason): # @UnusedVariable self.log.info('Disconnected: %s' % reason.getErrorMessage()) if not self._disconnecting: self._disconnectReason = StompConnectionError( 'Unexpected connection loss [%s]' % reason.getErrorMessage())
def connect(self, timeout=None): """ Allow older versions of ssl module, allow http proxy connections """ LOG.debug("stomp_transport.connect()") ssl_params = None if isinstance(self.sslContext, dict): # This is actually a dictionary of ssl parameters for wrapping the socket ssl_params = self.sslContext self.sslContext = None proxy_details = helpers.get_and_parse_proxy_env_var( constants.ENV_HTTPS_PROXY) proxy_type = socks.HTTP if helpers.is_env_proxies_set() and proxy_details: if helpers.is_in_no_proxy(self.host): self.proxy_host = None self.proxy_port = None self.proxy_user = None self.proxy_password = None else: self.proxy_host = proxy_details.get("hostname", "") self.proxy_port = proxy_details.get("port") self.proxy_user = proxy_details.get("username", "") self.proxy_password = proxy_details.get("password", "") try: if self.proxy_host: LOG.info("Connecting through proxy %s", self.proxy_host) self._socket = socks.socksocket() self._socket.set_proxy(proxy_type, self.proxy_host, self.proxy_port, True, username=self.proxy_user, password=self.proxy_password) else: self._socket = socket.socket() self._socket.settimeout(timeout) self._socket.connect((self.host, self.port)) if ssl_params: # For cases where we don't have a modern SSLContext (so no SNI) cert_required = ssl.CERT_REQUIRED if ssl_params[ "ca_certs"] else ssl.CERT_NONE self._socket = ssl.wrap_socket( self._socket, keyfile=ssl_params['key_file'], certfile=ssl_params['cert_file'], cert_reqs=cert_required, ca_certs=ssl_params['ca_certs'], ssl_version=ssl_params['ssl_version']) if cert_required: LOG.info("Performing manual hostname check") cert = self._socket.getpeercert() self.match_hostname(cert, self.host) if self.sslContext: self._socket = self.sslContext.wrap_socket( self._socket, server_hostname=self.host) except IOError as e: raise StompConnectionError('Could not establish connection [%s]' % e) self._parser.reset()