Exemplo n.º 1
0
def test_tornado_connection_basic_consume_outside_transaction(producer):
    def on_message(channel, method_frame, header_frame, body):
        assert hasattr(method_frame, '_nr_start_time')
        assert body == BODY
        channel.basic_ack(method_frame.delivery_tag)
        channel.close()
        connection.close()
        connection.ioloop.stop()

    def on_open_channel(channel):
        basic_consume(channel, QUEUE, on_message)

    def on_open_connection(connection):
        connection.channel(on_open_callback=on_open_channel)

    connection = TornadoConnection(pika.ConnectionParameters(
        DB_SETTINGS['host']),
                                   on_open_callback=on_open_connection)

    try:
        connection.ioloop.start()
    except:
        connection.close()
        connection.ioloop.stop()
        raise
class PikaClient(object):

    def __init__(self, username='******', exchange_name='ws', password='******', host='localhost', port=5672, virtual_host='/'):
	self.exchange_name = exchange_name

        # Options
        self.username = username
        self.password = password
        self.host = host
        self.port = port
        self.virtual_host = virtual_host

        # Default values
        self.connected = False
        self.connecting = False
        self.connection = None
        self.channel = None

    def connect(self):
        if self.connecting:
            pika.log.info('PikaClient: Already connecting to RabbitMQ')
            return
        pika.log.info('PikaClient: Connecting to RabbitMQ on localhost:5672')
        self.connecting = True

        credentials = pika.PlainCredentials(self.username, self.password)
        param = pika.ConnectionParameters(host=self.host,
                                          port=self.port,
                                          virtual_host=self.virtual_host,
                                          credentials=credentials)
        self.connection = TornadoConnection(param,
                                            on_open_callback=self.on_connected)
        self.connection.add_on_close_callback(self.on_closed)

    def on_connected(self, connection):
        pika.log.info('PikaClient: Connected to RabbitMQ on localhost:5672')
        self.connected = True
        self.connection = connection
        self.connection.channel(self.on_channel_open)

    def on_channel_open(self, channel):
        pika.log.info('PikaClient: Channel Open, Declaring Exchange')
        self.channel = channel

        self.channel.exchange_declare(exchange=self.exchange_name,
                                      type="direct",
                                      callback=self.on_exchange_declared)

    def on_exchange_declared(self, frame):
        pika.log.info('PikaClient: Exchange Declared, Ready for declaring Queues')

    def on_basic_cancel(self, frame):
        pika.log.info('PikaClient: Basic Cancel Ok')
        # If we don't have any more consumer processes running close
        self.connection.close()

    def on_closed(self, connection):
        # We've closed our pika connection so stop the demo
        tornado.ioloop.IOLoop.instance().stop()
Exemplo n.º 3
0
class PikaClient(object):
    callbacks = {}
    def __init__(self, callback_ins, port):
        self.callback_ins=callback_ins
        self.queue_name = "q%d" % uuid.uuid4().int
        if tornado is None:
            raise Exception('You must add tornado to your requirements!')
        if pika is None:
            raise Exception('You must add pika to your requirements!')

        self.ioloop = tornado.ioloop.IOLoop.instance()
        self.connection = None
        self.channel = None

        self._delivery_tag = 0
        self.parameters = pika.URLParameters("amqp://*****:*****@hostname:" + str(port) + "/%2F")

    def connect(self):
        self.connection = TornadoConnection(self.parameters, on_open_callback=self.on_connected, stop_ioloop_on_close=False)
        self.connection.add_on_close_callback(self.on_closed)


    def on_connected(self, connection):
        logger.info('PikaClient: connected to RabbitMQ')
        self.connection.channel(self.on_exchange_declare)


    def on_exchange_declare(self, channel):
        logger.info('PikaClient: Channel %s open, Declaring exchange' % channel)
        self.channel = channel
        self.channel.exchange_declare(self.on_queue_declare, exchange='compute', type='fanout')
        

    def on_queue_declare(self, method_frame):
        logger.info('PikaClient: Channel open, Declaring queue')
        self.result = self.channel.queue_declare(self.on_queue_bind, queue=self.queue_name, durable=True)


    def on_queue_bind(self, method_frame):
        logger.info('Queue bound')
        self.channel.queue_bind(self.on_consume_bind, queue=self.queue_name, exchange="compute")


    def on_consume_bind(self, frame):
        self.channel.basic_qos(prefetch_count=1)
        self.channel.basic_consume(self.on_response, queue=self.queue_name, no_ack=False)


    def on_response(self, channel, method, properties, body):
        message = body
        self.callback_ins.handle_rabbitmq_message(message)
        channel.basic_ack(delivery_tag = method.delivery_tag)  
        logger.info('Recieve a new Message: %r' % message)

    def on_closed(self, connection):
        logger.info('PikaClient: rabbit connection closed')
        self.connection.close()
        self.channel.close()
        self.ioloop.stop()
Exemplo n.º 4
0
class AMQPClient(object):

    channels = {}

    def __init__(self, uri, logger, on_connected_callback=None):
        self._uri = uri or 'amqp://*****:*****@localhost:5672/%2f'
        self._logger = logger or logging.getLogger(self.__class__.__name__)
        self._on_connected_callback = on_connected_callback
        self._amqp_connect()

    @property
    def uri(self):
        return self._uri

    @property
    def connection(self):
        return self._connection

    def __getattr__(self, name):
        if name in self.channels.keys():
            return self.channels[name]
        self.channels[name] = AMQPChannelClient(self, name)
        return self.channels[name]

    def __getitem__(self, name):
        return self.__getattr__(name)

    def _amqp_connect(self):
        self._connection = TornadoConnection(pika.URLParameters(self.uri),
            on_open_callback=self._on_amqp_opened, stop_ioloop_on_close=True)

    def _on_amqp_opened(self, connection):
        self._logger.debug('AMQP connection opened')
        self.connection.add_on_close_callback(self._on_connection_closed)
        if self._on_connected_callback:
            self._on_connected_callback()

    def _on_connection_closed(self, connection):
        #TODO: Log disconnection details...
        #self.log.warning('Server closed connection, reopening: (%s) %s',
                         #method_frame.method.reply_code,
                         #method_frame.method.reply_text)
        #self.log.debug(connection._is_method_frame())
        self._connection = self._amqp_connect()

    def close(self):
        for channel in self.channels.values():
            channel.cancel_consume()
        self._logger.debug('Closing AMQP connection')
        self._connection.close()
Exemplo n.º 5
0
class PikaConsumer(object):
    def __init__(self):
        if tornado is None:
            raise Exception('You must add tornado to your requirements!')
        if pika is None:
            raise Exception('You must add pika to your requirements!')

        self.ioloop = tornado.ioloop.IOLoop.instance()
        self.connection = None
        self.channel = None
        self._delivery_tag = 0
        self.parameters = None
        self.queue_name = None
        self.on_task_end = None

    def connect(self):
        self.connection = TornadoConnection(self.parameters,
                                            on_open_callback=self.on_connected,
                                            stop_ioloop_on_close=False)
        self.connection.add_on_close_callback(self.on_closed)

    def on_connected(self, connection):
        logger.info('PikaConsumer: connected to RabbitMQ')
        self.connection.channel(on_open_callback=self.on_channel_declared)

    def on_channel_declared(self, channel):
        self.channel = channel
        self.channel.queue_declare(self.on_queue_declared,
                                   queue=self.queue_name)

    def on_queue_declared(self, method_frame):
        self.channel.basic_qos(prefetch_count=1)
        self.channel.basic_consume(self.on_consume,
                                   queue=self.queue_name,
                                   no_ack=False)

    def on_closed(self, connection):
        logger.info('PikaConsumer: rabbit connection closed')
        self.connection.close()
        self.channel.close()
        self.ioloop.stop()

    def on_consume(self, channel, method, properties, body):
        try:
            if self.on_task_end:
                self.on_task_end(body)
        except Exception as e:
            logger.info('PikaConsumer: Error %r' % e)

        channel.basic_ack(delivery_tag=method.delivery_tag)
Exemplo n.º 6
0
class PikaClient(object):
    """A modified class as described in pika's demo_tornado.py.
    It handles the connection for the Tornado instance. Messaging/RPC
    callbacks are handled by the Tornado RequestHandler above."""
    def __init__(self):
        self.connecting = False
        self.connection = None
        self.channel = None
        #self.L = log_class.Logger()
    def connect(self):
        if self.connecting:
            log.info('Already connecting to RabbitMQ.')
            return
        #self.L.logger.info("Connecting to RabbitMQ")
        self.connecting = True
        creds = pika.PlainCredentials('guest', 'guest')
        params = pika.ConnectionParameters(host='localhost',
                                           port=5672,
                                           virtual_host='/',
                                           credentials=creds)
        self.connection = TornadoConnection(params,
                                            on_open_callback=self.on_connect)
        self.connection.add_on_close_callback(self.on_closed)

    def on_connect(self, connection):
        self.connection = connection
        connection.channel(self.on_channel_open)

    def on_channel_open(self, channel):
        #self.L.logger.info('Channel Open')
        self.channel = channel
        # I'm having trouble using named exchanges.
        ## channel.exchange_declare(exchange='rpc_ex', type='direct',
        ##                          auto_delete=True, durable=False,
        ##                          callback=self.on_exchange_declare)

    def on_exchange_declare(self, frame):
        log.info("Exchange declared.")

    def on_basic_cancel(self, frame):
        log.info('Basic Cancel Ok.')
        # If we don't have any more consumer processes running close
        self.connection.close()

    def on_closed(self, connection):
        # We've closed our pika connection so stop the demo
        tornado.ioloop.IOLoop.instance().stop()
Exemplo n.º 7
0
class PikaClient(object):
    """A modified class as described in pika's demo_tornado.py.
    It handles the connection for the Tornado instance. Messaging/RPC
    callbacks are handled by the Tornado RequestHandler above."""

    def __init__(self):
        self.connecting = False
        self.connection = None
        self.channel = None
        # self.L = log_class.Logger()

    def connect(self):
        if self.connecting:
            log.info("Already connecting to RabbitMQ.")
            return
        # self.L.logger.info("Connecting to RabbitMQ")
        self.connecting = True
        creds = pika.PlainCredentials("guest", "guest")
        params = pika.ConnectionParameters(host="localhost", port=5672, virtual_host="/", credentials=creds)
        self.connection = TornadoConnection(params, on_open_callback=self.on_connect)
        self.connection.add_on_close_callback(self.on_closed)

    def on_connect(self, connection):
        self.connection = connection
        connection.channel(self.on_channel_open)

    def on_channel_open(self, channel):
        # self.L.logger.info('Channel Open')
        self.channel = channel
        # I'm having trouble using named exchanges.
        ## channel.exchange_declare(exchange='rpc_ex', type='direct',
        ##                          auto_delete=True, durable=False,
        ##                          callback=self.on_exchange_declare)

    def on_exchange_declare(self, frame):
        log.info("Exchange declared.")

    def on_basic_cancel(self, frame):
        log.info("Basic Cancel Ok.")
        # If we don't have any more consumer processes running close
        self.connection.close()

    def on_closed(self, connection):
        # We've closed our pika connection so stop the demo
        tornado.ioloop.IOLoop.instance().stop()
Exemplo n.º 8
0
class PikaClient(object):

    def __init__(self, host, queue):
        self.queue = queue
        self.host = host
        self.connected = False
        self.connecting = False
        self.connection = None
        self.channel = None
        self.callbacks = {}

    def connect(self):
        if self.connecting:
            return
        self.connecting = True
        self.connection = TornadoConnection(
            pika.ConnectionParameters(host=self.host),
            on_open_callback=self.on_connected
        )
        self.connection.add_on_close_callback(self.on_closed)

    def on_connected(self, connection):
        self.connected = True
        self.connection = connection
        self.connection.channel(self.on_channel_open)

    def on_channel_open(self, chanel):
        self.channel = chanel
        self.channel.queue_declare(
            queue=self.queue,
            durable=True,
        )

    def on_basic_cancel(self, frame):
        self.connection.close()

    def on_closed(self, connection):
        tornado.ioloop.IOLoop.instance().stop()

    def send(self, body):
        self.channel.basic_publish(
            exchange='',
            routing_key=self.queue,
            body=json.dumps(body),
        )
Exemplo n.º 9
0
class Pika(object):

    """ rabbitMQ manager.  """

    def __init__(self):
        """ rabbitMQ manager init. """
        self.connection = None
        self.connecting = False
        self.channel = None

    def connect(self):
        """ rabbitMQ manager connect. """
        if self.connecting:
            logging.info('Already connecting to RabbitMQ')
            return
        logging.info('Connectiong to RabbitMQ')
        self.connecting = True
        credentials = pika.PlainCredentials('guest', 'guest')
        params = pika.ConnectionParameters(
            host='localhost',
            port=5672,
            virtual_host='/smsgo',
            credentials=credentials)
        self.connection = TornadoConnection(
            params, on_open_callback=self.on_connect)
        self.connection.add_on_close_callback(on_closed)

    def on_connect(self, connection):
        """ rabbitMQ manager on connect callback. """
        self.connection = connection
        connection.channel(self.on_channel_open)

    def on_channel_open(self, channel):
        """ rabbitMQ manager on channel open callback. """
        logging.info('Channel Open')
        self.channel = channel

    #def on_exchange_declare(self, frame):
        #logging.info('Exchange Declare')

    def on_basic_cancel(self, frame):
        """ rabbitMQ manager on basic cancel callback. """
        logging.info('Basic Cancel Ok')
        self.connection.close()
Exemplo n.º 10
0
class PikaClient(object):
    """A modified class as described in pika's demo_tornado.py.
    It handles the connection for the Tornado instance. Messaging/RPC
    callbacks are handled by the Tornado RequestHandler above."""

    def __init__(self):
        self.connecting = False
        self.connection = None
        self.channel = None

    def connect(self):
        # print 22222222
        if self.connecting:
            logger.info('Already connecting to RabbitMQ.')
            return
        logger.info("Connecting to RabbitMQ")
        self.connecting = True
        creds = pika.PlainCredentials('zyl', 'pwd_zyl')
        params = pika.ConnectionParameters(host='112.74.75.38', port=5672,
                                     credentials=creds)
        self.connection = TornadoConnection(params,
                                            on_open_callback=self.on_connect)
        self.connection.add_on_close_callback(self.on_closed)
        # print 4444444444

    def on_connect(self, connection):
        self.connection = connection
        connection.channel(self.on_channel_open)

    def on_channel_open(self, channel):
        logger.info('Channel Open')
        self.channel = channel

    def on_exchange_declare(self, frame):
        logger.info("Exchange declared.")

    def on_basic_cancel(self, frame):
        logger.info('Basic Cancel Ok.')
        # If we don't have any more consumer processes running close
        self.connection.close()

    def on_closed(self, connection):
        # We've closed our pika connection so stop the demo
        print 'close'
Exemplo n.º 11
0
class PikaClient(object):
    def __init__(self, host, queue):
        self.queue = queue
        self.host = host
        self.connected = False
        self.connecting = False
        self.connection = None
        self.channel = None
        self.callbacks = {}

    def connect(self):
        if self.connecting:
            return
        self.connecting = True
        self.connection = TornadoConnection(
            pika.ConnectionParameters(host=self.host),
            on_open_callback=self.on_connected)
        self.connection.add_on_close_callback(self.on_closed)

    def on_connected(self, connection):
        self.connected = True
        self.connection = connection
        self.connection.channel(self.on_channel_open)

    def on_channel_open(self, chanel):
        self.channel = chanel
        self.channel.queue_declare(
            queue=self.queue,
            durable=True,
        )

    def on_basic_cancel(self, frame):
        self.connection.close()

    def on_closed(self, connection):
        tornado.ioloop.IOLoop.instance().stop()

    def send(self, body):
        self.channel.basic_publish(
            exchange='',
            routing_key=self.queue,
            body=json.dumps(body),
        )
Exemplo n.º 12
0
class PikaProducer(object):
    def __init__(self):
        if tornado is None:
            raise Exception('You must add tornado to your requirements!')
        if pika is None:
            raise Exception('You must add pika to your requirements!')

        self.ioloop = tornado.ioloop.IOLoop.instance()
        self.connection = None
        self.channel = None
        self._delivery_tag = 0
        self.parameters = None
        self.queue_name = None

    def connect(self):
        self.connection = TornadoConnection(self.parameters,
                                            on_open_callback=self.on_connected,
                                            stop_ioloop_on_close=False)
        self.connection.add_on_close_callback(self.on_closed)

    def on_connected(self, connection):
        logger.info('PikaProducer: connected to RabbitMQ')
        self.connection.channel(on_open_callback=self.on_channel_declared)

    def on_channel_declared(self, channel):
        self.channel = channel
        self.channel.queue_declare(self.on_queue_declared,
                                   queue=self.queue_name)

    def on_queue_declared(self, method_frame):
        pass

    def publish(self, body):
        self.channel.basic_publish(exchange='',
                                   routing_key=self.queue_name,
                                   body=body)

    def on_closed(self, connection):
        logger.info('PikaProducer: rabbit connection closed')
        self.connection.close()
        self.channel.close()
Exemplo n.º 13
0
class PikaClient(object):
    def __init__(self):
        self.ioloop = tornado.ioloop.IOLoop.instance()
        self.connection = None
        self.channel = None

        self._delivery_tag = 0
        self.parameters = pika.ConnectionParameters(rabbitmq_server)

    def connect(self):
        self.connection = TornadoConnection(
            self.parameters,
            on_open_callback=self.on_connected,
            stop_ioloop_on_close=False,
            on_open_error_callback=self.on_open_error)
        self.connection.add_on_close_callback(self.on_closed)

    def on_open_error(self, unused_connection, err):
        sys.exit(1)

    def on_connected(self, connection):
        logging.info('PikaClient: connected to RabbitMQ')
        self.connection.channel(self.on_exchange_declare)

    def on_exchange_declare(self, channel):
        logging.info('PikaClient: Channel %s open, Declaring exchange' %
                     channel)
        self.channel = channel
        self.channel.exchange_declare(self.on_queue_declare,
                                      exchange='notification',
                                      exchange_type='direct')

    def on_queue_declare(self, method_frame):
        logging.info('PikaClient: Channel open, Declaring queue')
        self.channel.queue_declare(self.on_queue_bind,
                                   queue='notification')  #, durable=True)

    def on_queue_bind(self, method_frame):
        logging.info('Queue bound')
        self.channel.queue_bind(self.on_consume_bind,
                                queue="notification",
                                exchange="notification",
                                routing_key="notification")

    def on_consume_bind(self, frame):
        logging.info("Consume bind")
        self.channel.basic_qos(prefetch_count=1)
        self.channel.basic_consume(self.on_response,
                                   queue='notification',
                                   no_ack=False)

    def on_response(self, channel, method, properties, body):
        logging.info('on_response')
        message = pickle.loads(body)
        logging.info(message)
        ChatSocketHandler.on_caculate_success(message['id'], message['index'])
        channel.basic_ack(delivery_tag=method.delivery_tag)

    def on_closed(self, connection):
        logging.info('PikaClient: rabbit connection closed')
        self.connection.close()
        self.channel.close()
        self.ioloop.stop()
Exemplo n.º 14
0
class RabbitClient(object):

  EXCHANGE = 'message'
  EXCHANGE_TYPE = 'topic'
  PUBLISH_INTERVAL = .001
  QUEUE = 'text'
  ROUTING_KEY = 'example.text'

  def __init__(self, app, ioloop):
    """Setup the example publisher object, passing in the URL we will use
    to connect to RabbitMQ.

    :param str amqp_url: The URL for connecting to RabbitMQ

    """
    self._connection = None
    self._channel = None
    self._deliveries = []
    self._acked = 0
    self._nacked = 0
    self._message_number = 0
    self._stopping = False
    self.app = app
    self.ioloop = ioloop

  ## Connection Logic ##########################################################

  def connect(self):
    LOGGER.info('Connecting to RabbitMQ')
    # exc_type, exc_value, exc_traceback = sys.exc_info()
    # traceback.print_tb(exc_traceback, limit=None, file=sys.stdout)
    # self.connecting = True

    self._connection = TornadoConnection(rc.connParam,
      on_open_callback=self.on_connection_open)

  def close_connection(self):
    """This method closes the connection to RabbitMQ."""
    LOGGER.info('Closing connection')
    self._connection.close()

  def add_on_connection_close_callback(self):
    LOGGER.info('Adding connection close callback')
    self._connection.add_on_close_callback(self.on_connection_closed)

  def on_connection_closed(self, method_frame):
    # if we loose the connection, try to reconnect
    LOGGER.warning('Server closed connection, reopening: (%s) %s',
             method_frame.method.reply_code,
             method_frame.method.reply_text)
    self._channel = None
    self._connection = self.connect()

  def on_connection_open(self, unused_connection):
    LOGGER.info('Connection opened')
    self.add_on_connection_close_callback()
    self.open_channel()

  def add_on_channel_close_callback(self):
    LOGGER.info('Adding channel close callback')
    self._channel.add_on_close_callback(self.on_channel_closed)

  def on_channel_closed(self, method_frame):
    # if rabbit closes the channel, quit server
    LOGGER.warning('Channel was closed: (%s) %s',
             method_frame.method.reply_code,
             method_frame.method.reply_text)
    self._connection.close()

  def on_channel_open(self, channel):
    LOGGER.info('Channel opened')
    self._channel = channel
    self.add_on_channel_close_callback()
    self.setupExngsQueues()

  def sendNodeCtrlMsg(self, nodeHostname, ctrlCode):
    self._channel.basic_publish(
      rc.msgExngAttr["exchange"],
      "node.{0}.cmd".format(nodeHostname),
      str(ctrlCode)
    )

  ## Message Route Init ########################################################

  def setupExngsQueues(self):
    LOGGER.info('')
    self.exngQueCount = 0
    self.exngQueNum = len(rc.svrExngs) + len(rc.svrQueues)
    # open all exchanges and queues we need asynchronously
    for exng in rc.svrExngs:
      self.setupExchange(exng)
    for queue in rc.svrQueues:
      self.setupQueue(queue)
    # callback fn counts when everything is declared
  def setupExchange(self, exng):
    LOGGER.info('Declaring exchange %s', exng["exchange"])
    self._channel.exchange_declare(self.onExngQueDeclare, **exng)
  def setupQueue(self, queue):
    LOGGER.info('Declaring queue %s', queue["queue"])
    self._channel.queue_declare(self.onExngQueDeclare, **queue)

  def onExngQueDeclare(self, mystery=None): # got unknown return
    # check to see how many rabbit entities are declared
    self.exngQueCount = self.exngQueCount + 1
    LOGGER.info('Declared %d exchanges/queues.', self.exngQueCount)
    if(self.exngQueCount == self.exngQueNum):
      # all our exchanges and queues are accounted for; setup bindings
      self.setupBindings()

  def setupBindings(self):
    self.bindingsCount = 0
    self.bindingsNum = len(rc.svrBindings)
    for binding in rc.svrBindings:
      LOGGER.info('Binding exchange %s to queue %s', binding["exchange"],
        binding["queue"])
      self._channel.queue_bind(self.onBind, binding["queue"],
        binding["exchange"], binding["routing_key"])

  def onBind(self, mystery=None):
    # check to see if we made all our bindings
    self.bindingsCount = self.bindingsCount + 1
    LOGGER.info('Made %d bindings.', self.bindingsCount)
    if(self.bindingsCount == self.bindingsNum):
      # all of our bindings are accounted for; build message logic
      self.setupMsgRouting()
  def setupMsgRouting(self):
    # map the message queues we defined to our handlers
    LOGGER.info('Mapping handlers...')
    self._channel.basic_consume(self.valueHandler, rc.valueQueAttr["queue"],
      no_ack=True)
    self._channel.basic_consume(self.initNodeHandler,
      rc.handshakeQueAttr["queue"])
    self._channel.basic_consume(self.serverCmdHandler, rc.cmdQueAttr["queue"])
    self._channel.basic_consume(self.nErrHandler, rc.nErrQueAttr["queue"])
    LOGGER.info('Server ready!')


  ## Handlers ##################################################################

# [I 130116 01:17:40 wifiWattSrv:203] 
# Bad message (TypeError('not all arguments converted during string formatting',)):
# {'threadName': 'MainThread', 'name': '__main__', 'thread': 139807606114048, 'created': 1358317060.982559, 'process': 10225, 'processName': 'MainProcess',
# 'args': (<pika.channel.Channel object at 0x1b77590>,
#   <Basic.Deliver(['consumer_tag=ctag1.0', 'redelivered=True', 'routing_key=', 'delivery_tag=1', 'exchange=ww.valueUpdate'])>,
#   <BasicProperties(['delivery_mode=1', "headers={'hostname': 'applepi'}"])>, '2.9493'), 'module': 'wifiWattSrv', 'filename': 'wifiWattSrv.py', 'levelno': 20, 'exc_text': None, 'pathname': 'wifiWattSrv.py', 'lineno': 203, 'msg':
# 'Got new channel: %s, basicDeliver: %s, prop: %s, body: ', 'exc_info': None, 'funcName': 'valueHandler', 'relativeCreated': 252.96688079833984, 'levelname': 'INFO', 'msecs': 982.5589656829834}


  def valueHandler(self, channel, basicDeliver, prop, body):
    """
    :param pika.channel.Channel unused_channel: The channel object
    :param pika.Spec.Basic.Deliver: basic_deliver method
    :param pika.Spec.BasicProperties: properties
    :param str|unicode body: The message body
    """
    # attempt to parse message and check fields
    try:
      msgData = json.loads(body)
    except:
      LOGGER.error("Couldn't parse message. Malformed.")
      return -1
    if(("hostname" not in msgData)
      or ("current" not in msgData)
      or ("relayState" not in msgData)):
      LOGGER.error("Couldn't parse message. Mising fields.")
      return -1
    hostname = msgData["hostname"]
    value = float(msgData["current"])
    relayState = bool(int(msgData["relayState"]))
    # LOGGER.info("Raw: %s Parsed: %d", msgData["relayState"], int(relayState))

    # if we've inited this node, call it's append method
    if hostname in self.app.nodes:
      nodeObj = self.app.nodes[hostname]
      newDP = wifiWattNode.wwDataPoint(value, time.time())
      nodeObj.appendData(newDP, relayState)
    else:
      LOGGER.error('No node with hostname <%s>!', hostname)

    # attempt to read message header info
    # if "hostname" in prop.headers:
    #   hostname = prop.headers["hostname"]
    # else:
    #   LOGGER.error('Couldn\'t read hostname from message!')
    #   return -1
    # # parse the message 
    # value = float(body)
    # LOGGER.info('Got new value "%f" from hostname <%s>.', value, hostname)
    


  def initNodeHandler(self, channel, basicDeliver, prop, body):
    """
    Initialize the data stores for a node on the server. Works as a callback for
    a new message to the server handshake queue.
    """
    # parse the hostname from handshake message
    hostname = body
    nodes = self.app.nodes
    # check if we already have structures for this node
    if(hostname in nodes):
      # we have it already
      LOGGER.info('Got handshake for node <%s>; already exists.', hostname)
    else:
      # make a new node instance
      LOGGER.info('Initing new node for hostname: %s', hostname)
      newNode = wifiWattNode.wifiWattNode(hostname)
      nodes[hostname] = newNode
    # send back the prefered message rate to start value stream
    self._channel.basic_publish(
      rc.msgExngAttr["exchange"],
      "node.{0}.handshake".format(hostname),
      str(prefMsgRate)
    )
    # notify all our webclients that we have a new node
    for webClient in self.app.webClients:
      webClient.newNodeCb(newNode)

  def serverCmdHandler(self, channel, basicDeliver, prop, body):
    LOGGER.info('Got new command: %s', msg)

  def nErrHandler(self, channel, basicDeliver, prop, body):
    LOGGER.info('Got node error: %s', msg)

  def close_channel(self):
    """Invoke this command to close the channel with RabbitMQ by sending
    the Channel.Close RPC command.

    """
    LOGGER.info('Closing the channel')
    self._channel.close()

  def open_channel(self):
    """This method will open a new channel with RabbitMQ by issuing the
    Channel.Open RPC command. When RabbitMQ confirms the channel is open
    by sending the Channel.OpenOK RPC reply, the on_channel_open method
    will be invoked.

    """
    LOGGER.info('Creating a new channel')
    self._connection.channel(on_open_callback=self.on_channel_open)
Exemplo n.º 15
0
class PikaClient(object):

    def __init__(self, config: dict, exchanges: dict) -> None:
        self.connecting = False
        self.connection = None
        self.channel = None
        self.config = config
        self.exchanges = exchanges

    def connect(self):
        if self.connecting:
            logging.info('connecting - so not re-connecting')
            return
        self.connecting = True
        host = self.config.get('host')
        port = 5671 if self.config.get('amqps') else 5672
        scheme = 'amqps' if self.config.get('amqps') else 'amqp'
        virtual_host = urllib.parse.quote(self.config.get('vhost'), safe='')
        user = self.config.get('user')
        pw = self.config.get('pw')
        heartbeat = self.config.get('heartbeat') if self.config.get('heartbeat') else 0
        params = pika.URLParameters(
            f"{scheme}://{user}:{pw}@{host}:{port}/{virtual_host}?heartbeat={heartbeat}"
        )
        self.connection = TornadoConnection(params)
        self.connection.add_on_open_callback(self.on_connect)
        self.connection.add_on_close_callback(self.on_closed)
        self.connection.add_on_open_error_callback(self.on_open_error_callback)
        self.connecting = False
        return

    def on_open_error_callback(self, connection: TornadoConnection, exception: Exception) -> None:
        logging.error('could not connect')

    def on_connect(self, connection: TornadoConnection) -> None:
        self.connection = connection
        self.channel = self.connection.channel(
            on_open_callback=self.on_channel_open
        )
        return

    def on_channel_open(self, channel: pika.channel.Channel) -> None:
        for backend, config in self.exchanges.items():
            ex_name = config.get('exchange')
            channel.exchange_declare(
                ex_name,
                exchange_type='topic',
                durable=True,
            )
            logging.info(f'rabbitmq exchange: {ex_name} declared')
        return

    def on_basic_cancel(self, frame: pika.frame.Frame) -> None:
        self.connection.close()

    def on_closed(self, connection: TornadoConnection, exception: Exception) -> None:
        logging.info('rabbitmq connection closed')
        logging.info(exception)

    def publish_message(
        self,
        *,
        exchange: str,
        routing_key: str,
        method: str,
        uri: str,
        version: str,
        data: dict,
        persistent: bool = True,
        timestamp: int = int(time.time()),
    ) -> None:
        """
        Publilsh a message to an exchange.

        Parameters
        ----------
        exchange: str, exchange name
        routing_key: str, routing key for topic exchange
        method: str, HTTP method
        uri: str, HTTP request URI
        version: str, e.g. v1
        data: dict
        persistent: bool, default True
            tell rabbitmq to persist messages to disk, or not

        """
        data = {
            'method': method,
            'uri': uri,
            'version': version,
            'data': data,
        }
        message = json.dumps(data)
        delivery_mode = 2 if persistent else 1
        self.channel.basic_publish(
            exchange=exchange,
            routing_key=routing_key,
            body=message,
            properties=pika.BasicProperties(
                content_type='application/json',
                delivery_mode=delivery_mode,
                timestamp=timestamp,
                message_id=str(uuid.uuid4()),
            )
        )
        return
Exemplo n.º 16
0
class Dealer(object):
	def __init__(self,exchange,host,port):
		self.exchange   = exchange
		self.host       = host
		self.port       = port
		self.room_list  = {}


	def init_database(self):
		database.init_database()

		info =	DealerInfo.find(exchange = self.exchange)

		if not info:
			info = DealerInfo.new(self.exchange)
		else:
			print "WARNING, dealer %s already in database" % self.exchange


		info.rooms = 0
		self.info = info

	def on_queue_bound(self, frame):
		self.channel.basic_consume(
				consumer_callback=self.on_message,
				queue=self.queue_name, no_ack=True)


	def on_queue_declared(self, frame):
		self.queue_name = frame.method.queue
		self.channel.queue_bind(
				exchange    = self.exchange,
				queue       = self.queue_name,
				routing_key = 'dealer',
				callback=self.on_queue_bound)


	def on_exchange_declared(self,frame):
		self.channel.queue_declare(
				auto_delete = True,
				durable     = False,
				exclusive   = False,
				callback	=	self.on_queue_declared)


	def on_channel_open(self,channel):
		self.channel    = channel
		self.channel.exchange_declare(exchange = self.exchange,
				type        = 'topic',
				auto_delete = True,
				durable     = False,
				callback=self.on_exchange_declared
				)

	def on_connected(self,connection):
		connection.channel(self.on_channel_open)

	def start(self):
		credentials = pika.PlainCredentials('guest', 'guest')
		param = pika.ConnectionParameters(self.host,
						port=self.port,
						virtual_host="/",
						credentials=credentials)

		self.connection = TornadoConnection(param, on_open_callback=self.on_connected)
		self.connection.set_backpressure_multiplier(100000)

	def cmd_action(self, args):
		print "action in dealer %d" % args["action"]
		if args["room_id"] in self.room_list:
			current_room    = self.room_list[args["room_id"]]
			current_room.user_action(args)

	def cmd_chat(self, args):
		print args
		room	= self.room_list[args['room']]
		room.chat(args['user'], args['seat'], args['content'])

	def cmd_sit(self, args):
		print "sit received"
		source			= args['source']
		private_key		= args['private_key']
		stake			= args['stake']
		user			= User.find(_id=args['user_id'])
		print args['user_id']
		current_room	= self.room_list[args["room_id"]]
		(status, msg)	= current_room.sit(user, int(args["seat"]), source, private_key,stake)

		if status:
			message	= {"status": "success" }
		else:
			message = {"status": "failed", "msg": msg}
		self.channel.basic_publish( exchange    = self.exchange,
									routing_key = source,
									body        = json.dumps(message))

	def broadcast(self, routing_key, msg):
		self.channel.basic_publish(	exchange	= self.exchange,
									routing_key	= routing_key,
									body		= json.dumps(msg))

	def cmd_enter(self,args):
		routing_key = args['source']
		user_id = args['user_id']
		if args['room_id'] not in self.room_list:
			#self.cmd_create_room(args)
			message     = {'status':'failed'}
		else:
			current_room = self.room_list[args["room_id"]]

			message     = {'status':'success', "room":current_room.to_listener(user_id)}

		self.channel.basic_publish( exchange    = self.exchange,
				routing_key = routing_key,
				body        = json.dumps(message))
		#current_room.resend_last_next_message()


	def cmd_create_room(self, args):
		print "creating room"


		blind		= int(args["blind"])
		max_stake	= int(args["max_stake"])
		min_stake	= int(args["min_stake"])
		max_player	= int(args["max_player"])
		routing_key = args['source']
		roomType	= int(args["roomType"])


		newRoom = Room.new(self.exchange,blind,max_player,
				max_stake,
				min_stake,roomType)

		self.room_list[newRoom.id] = GameRoom(
				newRoom, args["user_id"], self,
				max_player,blind,min_stake,max_stake)
		print newRoom
		message = {"room_id":newRoom.id}

		self.channel.basic_publish( exchange    = self.exchange,
				routing_key = routing_key,
				body        = json.dumps(message))

		self.info.rooms += 1



	def on_message(self, channel, method, header, body):
		print "ON_MESSAGE!"
		obj = json.loads(body)
		print body
		method = getattr(self,"cmd_" + obj['method'])
		method(obj)

	def close(self):
		self.connection.close()


	def handle_init_file(self,fname,isDebug):
		info = Room.find_all(exchange = self.exchange)
		for room in info:
			room.remove()


	#	if os.path.isfile(fname):
		print len(fname)
		print os.getcwd()
		with open(fname) as f:
			for line in f:
				if line[0] == '#':
					continue

				(roomType,blind,max_stake,min_stake,max_player) = ( int(x) for x in line.strip().split(','))

				newRoom = Room.new(self.exchange,blind,max_player,
						max_stake,
						min_stake,roomType)
				self.room_list[newRoom.id] = GameRoom(
						newRoom, 1, self,
						max_player, blind, min_stake, max_stake)
				self.info.rooms += 1
				print newRoom
Exemplo n.º 17
0
class LoginPublish(object):

    def __init__(self):
        self.channel = None
        self.connection = None
        self.messages = []

    def initialcon(self):
        _logger.debug("pikapublish begin initialcon")
        credentials = pika.PlainCredentials('mxpub', 'mhearts2015')
        parameters =  pika.ConnectionParameters('localhost', 6500, credentials=credentials)
        self.connection = TornadoConnection(parameters, on_open_callback = self.on_connected)

    def on_connected(self, connection):
        _logger.debug("pikapublish begin on_connected")
        self.connection = connection
        self.connection.channel(self.on_channel_open)
        self.connection.add_on_close_callback(self.on_connection_closed)

    def on_connection_closed(self, connection, reply_code, reply_text):
        _logger.info("connection closed")
        self.connection.add_timeout(5, self.initialcon)

    def on_channel_open(self, channel):
        _logger.debug("pikapublish begin on_channel_open")
        self.channel = channel
        self.publishmsg()
        
    def releasecon(self):
        if self.connection:
            self.connection.close()

    def pushmsg(self, loginkey, body):
        _logger.debug("begin pushmsg %r  %s" % (body, loginkey))
        if not loginkey or not body:
            return

        self.messages.append({"key":loginkey, "body":body})
        self.publishmsg()

    def publishmsg(self):
        _logger.debug("begin to publishmsg")
        if not self.channel:
            _logger.debug("begin to open channel")
            self.initialcon()
            return

        for item in self.messages:
            key = item.get("key", "")
            body = item.get("body", "")

            _logger.info("begin to publish %s body = %r" % (key, body))
            if not isinstance(key, str) and not isinstance(key, bytes):
                _logger.error("invalid key")
                continue

            noti_body = json.dumps(body)
            try:
                self.channel.basic_publish(exchange = 'pclogin',
                                           routing_key = key,
                                           body = noti_body)
            except Exception as e:
                _logger.error("pikapublish  catch exception {0}".format(e))


        self.messages[:] = []
Exemplo n.º 18
0
class PikaClient(object):

    def __init__(self, config, app=None):
        self.classifier = Classifier()
        # Connection params
        self.host = config['host'] or 'localhost'
        self.port = config['port'] or '5672'
        self.vhost = config['vhost'] or '/'
        self.user = config['user'] or 'guest'
        self.passwd = config['passwd'] or 'guest'
        self.exchange = config['exchange'] or 'twitter2'
        self.queue_name = config['queue_name'] or 'twitter_topic_feed'
        self.routing_key = config['routing_key'] or 'twitter_topic_feed'

        # Default values
        self.connected = False
        self.connecting = False
        self.connection = None
        self.channel = None

        self.app = app
        self.event_listeners = set([])
        # A place for us to keep messages sent to us by Rabbitmq
        self.messages = list()

        # A place for us to put pending messages while we're waiting to connect
        self.pending = list()

        self.connect()

    def connect(self):
        if self.connecting:
            print('PikaClient: Already connecting to RabbitMQ')
            return
        print('PikaClient: Connecting to RabbitMQ on %s:%i' \
            % (self.host, self.port))
        self.connecting = True

        credentials = pika.PlainCredentials(self.user, self.passwd)

        param = pika.ConnectionParameters(host=self.host, port=self.port,
            virtual_host=self.vhost, credentials=credentials)

        logging.debug('Events: Connecting to AMQP Broker: %s:%i' % (self.host,
            self.port))

        # from pika.adapters import SelectConnection
        # connection = SelectConnection(parameters, on_connected)
        self.connection = TornadoConnection(param,
            on_open_callback=self.on_connected)

        self.connection.add_on_close_callback(self.on_closed)

    def on_connected(self, connection):
        print('PikaClient: Connected to RabbitMQ on %s:%i' \
            % (self.host, self.port))

        self.connected = True
        self.connection = connection
        self.connection.channel(self.on_channel_open)

    def on_channel_open(self, channel):
        print('PikaClient: Channel Open, Declaring Exchange %s' \
            % self.exchange)

        self.channel = channel
        self.channel.exchange_declare(exchange=self.exchange,
                                      type="direct",
                                      durable=False,
                                      callback=self.on_exchange_declared)

    def on_exchange_declared(self, frame):
        print('PikaClient: Exchange Declared, Declaring Queue %s' \
            % self.queue_name)
        self.channel.queue_declare(queue=self.queue_name,
                                   durable=False,
                                   exclusive=False,
                                   callback=self.on_queue_declared)

    def on_queue_declared(self, frame):
        print('PikaClient: Queue Declared, Binding Queue')
        self.channel.queue_bind(exchange=self.exchange,
                                queue=self.queue_name,
                                routing_key=self.routing_key,
                                callback=self.on_queue_bound)

    def on_queue_bound(self, frame):
        print('PikaClient: Queue Bound, Issuing Basic Consume')
        self.channel.basic_consume(consumer_callback=self.on_message,
                                   queue=self.queue_name,
                                   no_ack=True)
        # Send any messages pending
        for properties, body in self.pending:
            self.channel.basic_publish(exchange=self.exchange,
                                       routing_key=self.routing_key,
                                       body=body,
                                       properties=properties)

    def on_basic_cancel(self, frame):
        print('PikaClient: Basic Cancel Ok')
        # If we don't have any more consumer processes running close
        self.connection.close()

    def on_closed(self, connection):
        # We've closed our pika connection so stop the demo
        tornado.ioloop.IOLoop.instance().stop()

    def on_message(self, channel, method, header, body):
        print('PikaCient: Message received: %s delivery tag #%i: %s' \
           % (header.content_type, method.delivery_tag, body))

        # Append it to our messages list
        self.messages.append(body)

        self.app.dispatcher.notifyCallbacks(body)
        self.notify_listeners(body)
    
    def notify_listeners(self, event_obj):
        # here we assume the message the sourcing app
        # post to the message queue is in JSON format
        event_json = self.classify_text(event_obj)
        for listener in self.event_listeners: 
            listener.write_message(event_json)
            print('PikaClient: notified %s' % repr(listener))
 
    def add_event_listener(self, listener):
        self.event_listeners.add(listener)
        print('PikaClient: listener %s added' % repr(listener))
 
    def remove_event_listener(self, listener):
        try:
            self.event_listeners.remove(listener)
            print('PikaClient: listener %s removed' % repr(listener))
        except KeyError:
            pass

    def get_messages(self):
        # Get the messages to return, then empty the list
        output = self.messages
        self.messages = list()
        return output

    def publish(self, msg):
        # Build a message to publish to RabbitMQ
        #body = '%.8f: Request from %s [%s]' % \
        #       (tornado_request._start_time,
        #        tornado_request.remote_ip,
        #        tornado_request.headers.get("User-Agent"))

        # Send the message
        properties = pika.BasicProperties(content_type="text/plain",
                                          delivery_mode=1)
        self.channel.basic_publish(exchange=self.exchange,
                                   routing_key=self.routing_key,
                                   #body='Message: %s - %s' % (msg, body),
                                   body='Message: %s' % msg,
                                   properties=properties)
    
    def classify_text(self,event_json):
        #Temporaray: Processing should happen in intermediary handler
        #Parse JSON, return JSON with text geo and polarity
        print("CLASSIFIER MESSAGE " + event_json)
        parsedJson  =json.loads(event_json)
        tweettext = parsedJson['text'] 
        tweetgeo = parsedJson['geo']
        #tweetplace = parsedJson['place']
        #tweetcoords = parsedJson['coordinates']		
        tweet_polarity = self.classifier.classify(tweettext)
        return {'text':tweettext, 'geo': tweetgeo, 'polarity':tweet_polarity}#, 'place':tweetplace,'coordinates':tweetcoords}
Exemplo n.º 19
0
class PikaConsumer(object):

    EXCHANGE_TYPE = "topic"

    def __init__(self,
                 io_loop="",
                 amqp_url="",
                 exchange="",
                 queue_name="",
                 routing_key=""):
        self._io_loop = io_loop
        self._connection = None
        self._closing = False
        self._channel = None
        self._url = amqp_url
        self._consumer_tag = None
        self.QUEUE = queue_name or "default_queue"
        self.ROUTING_KEY = routing_key or "default.get_routing_key"
        self.EXCHANGE = exchange or "default_exchange"

        LOG.info("消费者绑定: 交换机{},类型{},队列名字{},路由前缀{}".format(
            self.EXCHANGE, self.EXCHANGE_TYPE, self.QUEUE, self.ROUTING_KEY))

    def connect(self):
        """连接到rabbitmq, 赋值给self._connection, 并调用self._on_connection_open方法"""
        self._connection = TornadoConnection(
            parameters=pika.URLParameters(self._url),
            on_open_callback=self._on_connection_open)

    def close_connection(self):
        self._connection.close()

    def _on_connection_open(self, unused_connection):
        """当rabbitmq被打开时, 设置基本信息"""
        self._add_on_connection_close_callback()
        self._open_channel()

    def _add_on_connection_close_callback(self):
        """当rabbitmq意外关闭与发布者的连接的时候, 调用关闭连接"""
        self._connection.add_on_close_callback(self._on_connection_closed)

    def _on_connection_closed(self, connection, reason):
        """当rabbitmq意外关闭的时候尝试重新连接"""
        self._channel = None
        if self._closing:
            self._io_loop.stop()
        else:
            LOG.warning("connection close, reopening in 5 seconds: %s", reason)
            self._connection.ioloop.call_later(5, self._reconnect)

    def _reconnect(self):
        """重新连接"""
        if not self._closing:
            self._connection = self.connect()

    def _open_channel(self):
        """发布channel, 打开一个新的rabbitmq渠道...成功的时候将调用self._on_channel_open"""
        self._connection.channel(on_open_callback=self._on_channel_open)

    def _on_channel_open(self, channel):
        """当通道打开的时候, 我们申明使用的交换信息"""
        self._channel = channel
        self._add_on_channel_close_callback()
        self._set_exchange(self.EXCHANGE)

    def _add_on_channel_close_callback(self):
        """设置通道关闭回调"""
        self._channel.add_on_close_callback(self._on_channel_closed)

    def _on_channel_closed(self, channel, reason):
        self._connection.close()

    def _set_exchange(self, exchange_name):
        LOG.info('Declaring exchange %s', exchange_name)
        self._channel.exchange_declare(callback=self._on_exchange_declareok,
                                       exchange=exchange_name,
                                       exchange_type=self.EXCHANGE_TYPE)

    def _on_exchange_declareok(self, unused_frame):
        self._setup_queue(self.QUEUE)

    def _setup_queue(self, queue_name):
        self._channel.queue_declare(callback=self._on_queue_declareok,
                                    queue=queue_name)

    def _on_queue_declareok(self, method_frame):
        self._channel.queue_bind(callback=self._on_bindok,
                                 queue=self.QUEUE,
                                 exchange=self.EXCHANGE,
                                 routing_key=self.ROUTING_KEY)

    def _on_bindok(self, unused_frame):
        self._start_consuming()

    def _start_consuming(self):
        self._add_on_cancel_callback()
        self._consumer_tag = self._channel.basic_consume(
            on_message_callback=self._on_message, queue=self.QUEUE)

    def _add_on_cancel_callback(self):
        self._channel.add_on_cancel_callback(self._on_consumer_cancelled)

    def _on_consumer_cancelled(self, method_frame):
        if self._channel:
            self._channel.close()

    def _on_message(self, channel, basic_deliver, properties, body):
        """
            作为消费者接受消息,并做处理
        """
        # LOG.info("rabbitmq get body: %s", str(body))
        code, return_data = self.handler_body(body)
        return_exchange = properties.message_id
        return_routing_key = properties.reply_to
        # return_correlation_id = properties.correlation_id

        if (return_exchange and return_routing_key and return_data and code):
            # LOG.info(
            #     "send msg to rabbitmq: exchange: %s, routing_key: %s, body: %s",
            #     return_exchange, return_routing_key, return_data)

            # props = pika.BasicProperties(correlation_id=return_correlation_id)

            channel.basic_publish(exchange=return_exchange,
                                  body=json.dumps(return_data),
                                  routing_key=return_routing_key)
        elif code:
            LOG.warning("request properties info: %s",
                        [return_exchange, return_routing_key])
        if code:
            self._acknowledge_message(basic_deliver.delivery_tag)

    def _acknowledge_message(self, delivery_tag):
        self._channel.basic_ack(delivery_tag)

    def handler_body(self, body):
        return True, "ok"
Exemplo n.º 20
0
class PikaClient(object):

    def __init__(self):
        # Construct a queue name we'll use for this instance only
        self.queue_name = 'tornado-test-%i' % os.getpid()

        # Default values
        self.connected = False
        self.connecting = False
        self.connection = None
        self.channel = None

        # A place for us to keep messages sent to us by Rabbitmq
        self.messages = list()

        # A place for us to put pending messages while we're waiting to connect
        self.pending = list()

    def connect(self):
        if self.connecting:
            pika.log.info('PikaClient: Already connecting to RabbitMQ')
            return
        pika.log.info('PikaClient: Connecting to RabbitMQ on localhost:5672')
        self.connecting = True

        credentials = pika.PlainCredentials('guest', 'guest')
        param = pika.ConnectionParameters(host='localhost',
                                          port=5672,
                                          virtual_host="/",
                                          credentials=credentials)
        self.connection = TornadoConnection(param,
                                            on_open_callback=self.on_connected)
        self.connection.add_on_close_callback(self.on_closed)

    def on_connected(self, connection):
        pika.log.info('PikaClient: Connected to RabbitMQ on localhost:5672')
        self.connected = True
        self.connection = connection
        self.connection.channel(self.on_channel_open)

    def on_channel_open(self, channel):
        pika.log.info('PikaClient: Channel Open, Declaring Exchange')
        self.channel = channel
        self.channel.exchange_declare(exchange='tornado',
                                      type="direct",
                                      auto_delete=True,
                                      durable=False,
                                      callback=self.on_exchange_declared)

    def on_exchange_declared(self, frame):
        pika.log.info('PikaClient: Exchange Declared, Declaring Queue')
        self.channel.queue_declare(queue=self.queue_name,
                                   auto_delete=True,
                                   durable=False,
                                   exclusive=False,
                                   callback=self.on_queue_declared)

    def on_queue_declared(self, frame):
        pika.log.info('PikaClient: Queue Declared, Binding Queue')
        self.channel.queue_bind(exchange='tornado',
                                queue=self.queue_name,
                                routing_key='tornado.*',
                                callback=self.on_queue_bound)

    def on_queue_bound(self, frame):
        pika.log.info('PikaClient: Queue Bound, Issuing Basic Consume')
        self.channel.basic_consume(consumer_callback=self.on_pika_message,
                                   queue=self.queue_name,
                                   no_ack=True)
        # Send any messages pending
        for properties, body in self.pending:
            self.channel.basic_publish(exchange='tornado',
                                       routing_key='tornado.*',
                                       body=body,
                                       properties=properties)

    def on_pika_message(self, channel, method, header, body):
        pika.log.info('PikaCient: Message receive, delivery tag #%i' % \
                     method.delivery_tag)
        # Append it to our messages list
        self.messages.append(body)

    def on_basic_cancel(self, frame):
        pika.log.info('PikaClient: Basic Cancel Ok')
        # If we don't have any more consumer processes running close
        self.connection.close()

    def on_closed(self, connection):
        # We've closed our pika connection so stop the demo
        tornado.ioloop.IOLoop.instance().stop()

    def sample_message(self, tornado_request):
        # Build a message to publish to RabbitMQ
        body = '%.8f: Request from %s [%s]' % \
               (tornado_request._start_time,
                tornado_request.remote_ip,
                tornado_request.headers.get("User-Agent"))

        # Send the message
        properties = pika.BasicProperties(content_type="text/plain",
                                          delivery_mode=1)
        self.channel.basic_publish(exchange='tornado',
                                   routing_key='tornado.*',
                                   body=body,
                                   properties=properties)

    def get_messages(self):
        # Get the messages to return, then empty the list
        output = self.messages
        self.messages = list()
        return output
Exemplo n.º 21
0
Arquivo: chat.py Projeto: ryr/hipochat
class PikaClient(object):
    def __init__(self, io_loop):
        self.connected = False
        self.connecting = False
        self.connection = None
        self.channel = None
        self.ioloop = io_loop

    def connect(self):

        if self.connecting:
            logger.info('PikaClient: Already connecting to RabbitMQ')
            return

        logger.info('PikaClient: Connecting to RabbitMQ on port 5672, Object: %s', self)

        self.connecting = True

        credentials = pika.PlainCredentials(RABBIT_USERNAME, RABBIT_PASS)
        param = pika.ConnectionParameters(host=RABBIT_URL,
                                          port=5672,
                                          virtual_host='/',
                                          credentials=credentials)
        self.connection = TornadoConnection(param,
                                            on_open_callback=self.on_connected)

        global pika_connected
        pika_connected = True

    def on_connected(self, connection):
        logger.info('PikaClient: Connected to RabbitMQ on :5672')
        self.connected = True
        self.connection = connection
        self.connection.channel(self.on_channel_open)

    def on_channel_open(self, channel):
        logger.info('PikaClient: Channel Open, Declaring Exchange, Channel ID: %s', channel)
        self.channel = channel

        self.channel.exchange_declare(exchange='tornado',
                                      type='direct',
                                      durable=False,
                                      auto_delete=True)

    def declare_queue(self, token):
        logger.info('PikaClient: Exchange Declared, Declaring Queue')
        self.queue_name = token
        self.channel.queue_declare(queue=self.queue_name,
                                   durable=False,
                                   auto_delete=True,
                                   callback=self.on_queue_declared)

    def on_queue_declared(self, frame):
        self.channel.queue_bind(exchange='tornado',
                                queue=self.queue_name,
                                routing_key=self.queue_name,
                                callback=self.on_queue_bound)

    def on_queue_bound(self, frame):
        logger.info('PikaClient: Queue Bound, Issuing Basic Consume')
        self.channel.basic_consume(consumer_callback=self.on_pika_message,
                                   queue=self.queue_name,
                                   no_ack=True)

    def on_pika_message(self, channel, method, header, body):
        logger.info('PikaCient: Message receive, delivery tag #%i', method.delivery_tag)
        message = json.loads(body)
        for i in websockets[message['token']]:
            try:
                i.write_message(body)
            except:
                logger.exception('exception while writing message to client')

    def on_basic_cancel(self, frame):
        logger.info('PikaClient: Basic Cancel Ok')
        # If we don't have any more consumer processes running close
        self.connection.close()

    def on_closed(self, connection):
        # We've closed our pika connection so stop the demo
        self.ioloop.IOLoop.instance().stop()

    def sample_message(self, ws_msg):
        token = json.loads(ws_msg)['token']
        properties = pika.BasicProperties(
            content_type='text/plain', delivery_mode=1)
        self.channel.basic_publish(exchange='tornado',
                                   routing_key=token,
                                   body=ws_msg,
                                   properties=properties)
Exemplo n.º 22
0
class PikaClient(object):
    def __init__(self, io_loop):
        self.connected = False
        self.connecting = False
        self.connection = None
        self.channel = None
        self.ioloop = io_loop

    def connect(self):

        if self.connecting:
            logger.info('PikaClient: Already connecting to RabbitMQ')
            return

        logger.info(
            'PikaClient: Connecting to RabbitMQ on port 5672, Object: %s',
            self)

        self.connecting = True

        credentials = pika.PlainCredentials(RABBIT_USERNAME, RABBIT_PASS)
        param = pika.ConnectionParameters(host=RABBIT_URL,
                                          port=5672,
                                          virtual_host="/",
                                          credentials=credentials)
        self.connection = TornadoConnection(param,
                                            on_open_callback=self.on_connected)

        global pika_connected
        pika_connected = True

    def on_connected(self, connection):
        logger.info('PikaClient: Connected to RabbitMQ on :5672')
        self.connected = True
        self.connection = connection
        self.connection.channel(self.on_channel_open)

    def on_channel_open(self, channel):
        logger.info(
            'PikaClient: Channel Open, Declaring Exchange, Channel ID: %s',
            channel)
        self.channel = channel

        self.channel.exchange_declare(exchange='tornado',
                                      type="direct",
                                      durable=False,
                                      auto_delete=True)

    def declare_queue(self, token):
        logger.info('PikaClient: Exchange Declared, Declaring Queue')
        self.queue_name = token
        self.channel.queue_declare(queue=self.queue_name,
                                   durable=False,
                                   auto_delete=True,
                                   callback=self.on_queue_declared)

    def on_queue_declared(self, frame):
        self.channel.queue_bind(exchange='tornado',
                                queue=self.queue_name,
                                routing_key=self.queue_name,
                                callback=self.on_queue_bound)

    def on_queue_bound(self, frame):
        logger.info('PikaClient: Queue Bound, Issuing Basic Consume')
        self.channel.basic_consume(consumer_callback=self.on_pika_message,
                                   queue=self.queue_name,
                                   no_ack=True)

    def on_pika_message(self, channel, method, header, body):
        logger.info('PikaCient: Message receive, delivery tag #%i',
                    method.delivery_tag)
        message = json.loads(body)
        for i in websockets[message['token']]:
            try:
                i.write_message(body)
            except:
                logger.exception("exception while writing message to client")

    def on_basic_cancel(self, frame):
        logger.info('PikaClient: Basic Cancel Ok')
        # If we don't have any more consumer processes running close
        self.connection.close()

    def on_closed(self, connection):
        # We've closed our pika connection so stop the demo
        self.ioloop.IOLoop.instance().stop()

    def sample_message(self, ws_msg):
        token = json.loads(ws_msg)['token']
        properties = pika.BasicProperties(content_type="text/plain",
                                          delivery_mode=1)
        self.channel.basic_publish(exchange='tornado',
                                   routing_key=token,
                                   body=ws_msg,
                                   properties=properties)
Exemplo n.º 23
0
class AsyncTransport(BaseTransport):
    def _connect(self):
        self._connection = TornadoConnection(
            self._parameters,
            on_open_callback=self.on_connection_open,
            stop_ioloop_on_close=False
        )

    def on_connection_open(self, unused_connection):
        """This method is called by pika once the connection to RabbitMQ has
        been established. It passes the handle to the connection object in
        case we need it, but in this case, we'll just mark it unused.

        :type unused_connection: pika.SelectConnection

        """
        self._connection.add_on_close_callback(self.on_connection_closed)
        self._open_channel()

    def on_connection_closed(self, method_frame):
        self._connection = None
        self._connect()

    def close(self):
        self._connection.close()

    def _open_channel(self):
        """Open a new channel with RabbitMQ by issuing the Channel.Open RPC
        command. When RabbitMQ responds that the channel is open, the
        on_channel_open callback will be invoked by pika.

        """
        self._connection.channel(self._on_channel_open)

    def _on_channel_open(self, channel):
        self._channel = channel
        self._channel.basic_qos(prefetch_count=1)
        self.add_on_channel_close_callback()
        self.setup_exchange()

    def add_on_channel_close_callback(self):
        """This method tells pika to call the on_channel_closed method if
        RabbitMQ unexpectedly closes the channel.

        """
        self._channel.add_on_close_callback(self.on_channel_closed)

    def on_channel_closed(self, channel, reply_code, reply_text):
        """Invoked by pika when RabbitMQ unexpectedly closes the channel.
        Channels are usually closed if you attempt to do something that
        violates the protocol, such as re-declare an exchange or queue with
        different parameters. In this case, we'll close the connection
        to shutdown the object.

        :param pika.channel.Channel: The closed channel
        :param int reply_code: The numeric reason the channel was closed
        :param str reply_text: The text reason the channel was closed

        """
        LOGGER.warning('Channel %i was closed: (%s) %s',
                       channel, reply_code, reply_text)
        self._connection.close()

    def setup_exchange(self):
        """Setup the exchange on RabbitMQ by invoking the Exchange.Declare RPC
        command. When it is complete, the on_exchange_declareok method will
        be invoked by pika.

        :param str|unicode exchange_name: The name of the exchange to declare

        """
        self._channel.exchange_declare(self.on_exchange_declareok,
                                       self.EXCHANGE_NAME,
                                       self.EXCHANGE_TYPE)

    def on_exchange_declareok(self, unused_frame):
        """Invoked by pika when RabbitMQ has finished the Exchange.Declare RPC
        command.

        :param pika.Frame.Method unused_frame: Exchange.DeclareOk response frame

        """
        LOGGER.info('Exchange declared')
        self.setup_queue(self.QUEUE)

    def setup_queue(self, queue_name):
        """Setup the queue on RabbitMQ by invoking the Queue.Declare RPC
        command. When it is complete, the on_queue_declareok method will
        be invoked by pika.

        :param str|unicode queue_name: The name of the queue to declare.

        """
        LOGGER.info('Declaring queue %s', queue_name)
        self._channel.queue_declare(self.on_queue_declareok, queue_name)

    def on_queue_declareok(self, method_frame):
        """Method invoked by pika when the Queue.Declare RPC call made in
        setup_queue has completed. In this method we will bind the queue
        and exchange together with the routing key by issuing the Queue.Bind
        RPC command. When this command is complete, the on_bindok method will
        be invoked by pika.

        :param pika.frame.Method method_frame: The Queue.DeclareOk frame

        """
        LOGGER.info('Binding %s to %s with %s',
                    self.EXCHANGE_NAME, self.QUEUE, self.ROUTING_KEY)
        self._channel.queue_bind(self.on_bindok, self.QUEUE,
                                 self.EXCHANGE_NAME, self.ROUTING_KEY)

    def add_on_cancel_callback(self):
        """Add a callback that will be invoked if RabbitMQ cancels the consumer
        for some reason. If RabbitMQ does cancel the consumer,
        on_consumer_cancelled will be invoked by pika.

        """
        LOGGER.info('Adding consumer cancellation callback')
        self._channel.add_on_cancel_callback(self.on_consumer_cancelled)

    def on_consumer_cancelled(self, method_frame):
        """Invoked by pika when RabbitMQ sends a Basic.Cancel for a consumer
        receiving messages.

        :param pika.frame.Method method_frame: The Basic.Cancel frame

        """
        LOGGER.info('Consumer was cancelled remotely, shutting down: %r',
                    method_frame)
        if self._channel:
            self._channel.close()

    def acknowledge_message(self, delivery_tag):
        """Acknowledge the message delivery from RabbitMQ by sending a
        Basic.Ack RPC method for the delivery tag.

        :param int delivery_tag: The delivery tag from the Basic.Deliver frame

        """
        LOGGER.info('Acknowledging message %s', delivery_tag)
        self._channel.basic_ack(delivery_tag)

    def on_message(self, unused_channel, basic_deliver, properties, body):
        """Invoked by pika when a message is delivered from RabbitMQ. The
        channel is passed for your convenience. The basic_deliver object that
        is passed in carries the exchange, routing key, delivery tag and
        a redelivered flag for the message. The properties passed in is an
        instance of BasicProperties with the message properties and the body
        is the message that was sent.

        :param pika.channel.Channel unused_channel: The channel object
        :param pika.Spec.Basic.Deliver: basic_deliver method
        :param pika.Spec.BasicProperties: properties
        :param str|unicode body: The message body

        """
        LOGGER.info('Received message # %s from %s: %s',
                    basic_deliver.delivery_tag, properties.app_id, body)

        self.work_q.put(json.loads(body))
        self.acknowledge_message(basic_deliver.delivery_tag)

    def on_cancelok(self, unused_frame):
        """This method is invoked by pika when RabbitMQ acknowledges the
        cancellation of a consumer. At this point we will close the channel.
        This will invoke the on_channel_closed method once the channel has been
        closed, which will in-turn close the connection.

        :param pika.frame.Method unused_frame: The Basic.CancelOk frame

        """
        LOGGER.info('RabbitMQ acknowledged the cancellation of the consumer')
        self.close_channel()

    def stop_consuming(self):
        """Tell RabbitMQ that you would like to stop consuming by sending the
        Basic.Cancel RPC command.

        """
        if self._channel:
            LOGGER.info('Sending a Basic.Cancel RPC command to RabbitMQ')
            self._channel.basic_cancel(self.on_cancelok, self._consumer_tag)

    def start_consuming(self):
        """This method sets up the consumer by first calling
        add_on_cancel_callback so that the object is notified if RabbitMQ
        cancels the consumer. It then issues the Basic.Consume RPC command
        which returns the consumer tag that is used to uniquely identify the
        consumer with RabbitMQ. We keep the value to use it when we want to
        cancel consuming. The on_message method is passed in as a callback pika
        will invoke when a message is fully received.

        """
        LOGGER.info('Issuing consumer related RPC commands')
        self.add_on_cancel_callback()
        self._consumer_tag = self._channel.basic_consume(self.on_message,
                                                         self.QUEUE)

    def on_bindok(self, unused_frame):
        """Invoked by pika when the Queue.Bind method has completed. At this
        point we will start consuming messages by calling start_consuming
        which will invoke the needed RPC commands to start the process.

        :param pika.frame.Method unused_frame: The Queue.BindOk response frame

        """
        LOGGER.info('Queue bound')
        self.start_consuming()
Exemplo n.º 24
0
class PikaClient(object):

    def __init__(self, io_loop):
        self.connected = False
        self.connecting = False
        self.connection = None
        self.channel = None
        self.ioloop = io_loop

    def connect(self):

        if self.connecting:
                logger.info('PikaClient: Already connecting to RabbitMQ')
                return

        logger.info('PikaClient: Connecting to RabbitMQ on port 5672, Object: %s', self)

        self.connecting = True

        credentials = pika.PlainCredentials(RABBIT_USERNAME, RABBIT_PASS)
        param = pika.ConnectionParameters(host=RABBIT_URL,
                                         port=5672,
                                          virtual_host=RABBIT_VHOST,
                                          credentials=credentials)
        self.connection = TornadoConnection(param,
                                            on_open_callback=self.on_connected)
        logger.info("Connection to rabbit")
        global pika_connected
        pika_connected = True

    def on_connected(self, connection):
        logger.info('PikaClient: Connected to RabbitMQ on :5672')
        self.connected = True
        self.connection = connection
        self.connection.channel(self.on_channel_open)

    def on_channel_open(self, channel):
        logger.info('PikaClient: Channel Open, Declaring Exchange, Channel ID: %s', channel)
        self.channel = channel
        logger.info("setting channel")
        logger.info(channel)
        self.channel.exchange_declare(exchange='tornado',
                                      type="direct",
                                      durable=False,
                                      auto_delete=True)

    def declare_queue(self, token):
        logger.info('PikaClient: Exchange Declared, Declaring Queue')
        self.queue_name = token
        self.channel.queue_declare(queue=self.queue_name,
                                   durable=False,
                                   auto_delete=True,
                                   callback=self.on_queue_declared)

    def on_queue_declared(self, frame):
        self.channel.queue_bind(exchange='tornado',
                                queue=self.queue_name,
                                routing_key=self.queue_name,
                                callback=self.on_queue_bound)

    def on_queue_bound(self, frame):
        logger.info('PikaClient: Queue Bound, Issuing Basic Consume')
        self.channel.basic_consume(consumer_callback=self.on_pika_message,
                                   queue=self.queue_name,
                                   no_ack=True)

    def on_pika_message(self, channel, method, header, body):
        logger.info('PikaCient: Message receive, delivery tag #%i', method.delivery_tag)
        message = json.loads(body)
        # TODO: decrement unread count
        for i in websockets[message['token']]:
            try:
                if 'action' in message and message["action"] == "kick" and 'token_to_kick' in message:
                    if i.authentication_token == message["token_to_kick"]:
                        REDIS_CONNECTION.srem('%s-%s' % ('members', message['token']), message["token_to_kick"])
                        i.close()
                        continue
                    del message["token_to_kick"]
                    del message["action"]
                    body = json.dumps(message)
                i.write_message(body)
            except Exception as error:
                logger.exception("exception while writing message to client: {}".format(error.message))

    def on_basic_cancel(self, frame):
        logger.info('PikaClient: Basic Cancel Ok')
        # If we don't have any more consumer processes running close
        self.connection.close()

    def on_closed(self, connection):
        # We've closed our pika connection so stop the demo
        self.ioloop.IOLoop.instance().stop()

    def sample_message(self, ws_msg):
        logger.info(ws_msg)
        logger.info("zaa")
        token = json.loads(ws_msg)['token']
        properties = pika.BasicProperties(
            content_type="text/plain", delivery_mode=1)
        logger.info(self.channel)
        self.channel.basic_publish(exchange='tornado',
                                   routing_key=token,
                                   body=ws_msg,
                                   properties=properties)
Exemplo n.º 25
0
class ExamplePublisher(object):
  """This is an example publisher that will handle unexpected interactions
  with RabbitMQ such as channel and connection closures.

  If RabbitMQ closes the connection, it will reopen it. You should
  look at the output, as there are limited reasons why the connection may
  be closed, which usually are tied to permission related issues or
  socket timeouts.

  It uses delivery confirmations and illustrates one way to keep track of
  messages that have been sent and if they've been confirmed by RabbitMQ.

  """
  EXCHANGE = 'message'
  EXCHANGE_TYPE = 'topic'
  PUBLISH_INTERVAL = .001
  QUEUE = 'text'
  ROUTING_KEY = 'example.text'

  def __init__(self, app, ioloop):
    """Setup the example publisher object, passing in the URL we will use
    to connect to RabbitMQ.

    :param str amqp_url: The URL for connecting to RabbitMQ

    """
    self._connection = None
    self._channel = None
    self._deliveries = []
    self._acked = 0
    self._nacked = 0
    self._message_number = 0
    self._stopping = False
    self.app = app
    self.ioloop = ioloop

  def connect(self):
    LOGGER.info('Connecting to RabbitMQ')
    # exc_type, exc_value, exc_traceback = sys.exc_info()
    # traceback.print_tb(exc_traceback, limit=None, file=sys.stdout)
    # self.connecting = True

    self._connection = TornadoConnection(rc.connParam,
      on_open_callback=self.on_connection_open)

  def close_connection(self):
    """This method closes the connection to RabbitMQ."""
    LOGGER.info('Closing connection')
    self._connection.close()

  def add_on_connection_close_callback(self):
    """This method adds an on close callback that will be invoked by pika
    when RabbitMQ closes the connection to the publisher unexpectedly.

    """
    LOGGER.info('Adding connection close callback')
    self._connection.add_on_close_callback(self.on_connection_closed)

  def on_connection_closed(self, method_frame):
    """This method is invoked by pika when the connection to RabbitMQ is
    closed unexpectedly. Since it is unexpected, we will reconnect to
    RabbitMQ if it disconnects.

    :param pika.frame.Method method_frame: The method frame from RabbitMQ

    """
    LOGGER.warning('Server closed connection, reopening: (%s) %s',
             method_frame.method.reply_code,
             method_frame.method.reply_text)
    self._channel = None
    self._connection = self.connect()

  def on_connection_open(self, unused_connection):
    """This method is called by pika once the connection to RabbitMQ has
    been established. It passes the handle to the connection object in
    case we need it, but in this case, we'll just mark it unused.

    :type unused_connection: pika.SelectConnection

    """
    LOGGER.info('Connection opened')
    self.add_on_connection_close_callback()
    self.open_channel()

  def add_on_channel_close_callback(self):
    """This method tells pika to call the on_channel_closed method if
    RabbitMQ unexpectedly closes the channel.

    """
    LOGGER.info('Adding channel close callback')
    self._channel.add_on_close_callback(self.on_channel_closed)

  def on_channel_closed(self, method_frame):
    """Invoked by pika when RabbitMQ unexpectedly closes the channel.
    Channels are usually closed if you attempt to do something that
    violates the protocol, such as redeclare an exchange or queue with
    different paramters. In this case, we'll close the connection
    to shutdown the object.

    :param pika.frame.Method method_frame: The Channel.Close method frame

    """
    LOGGER.warning('Channel was closed: (%s) %s',
             method_frame.method.reply_code,
             method_frame.method.reply_text)
    self._connection.close()

  def on_channel_open(self, channel):
    """This method is invoked by pika when the channel has been opened.
    The channel object is passed in so we can make use of it.

    Since the channel is now open, we'll declare the exchange to use.

    :param pika.channel.Channel channel: The channel object

    """
    LOGGER.info('Channel opened')
    self._channel = channel
    self.add_on_channel_close_callback()
    self.setup_exchange()

  def setup_exchange(self):
    """Setup the exchange on RabbitMQ by invoking the Exchange.Declare RPC
    command. When it is complete, the on_exchange_declareok method will
    be invoked by pika.

    :param str|unicode exchange_name: The name of the exchange to declare

    """
    LOGGER.info('Declaring exchange %s', rc.valueExngAttr["exchange"])
    self._channel.exchange_declare(self.on_exchange_declareok,
      **rc.valueExngAttr)

  def on_exchange_declareok(self, unused_frame):
    """Invoked by pika when RabbitMQ has finished the Exchange.Declare RPC
    command.

    :param pika.Frame.Method unused_frame: Exchange.DeclareOk response frame

    """
    LOGGER.info('Exchange declared')
    self.setup_queue(self.QUEUE)

  def setup_queue(self, queue_name):
    """Setup the queue on RabbitMQ by invoking the Queue.Declare RPC
    command. When it is complete, the on_queue_declareok method will
    be invoked by pika.

    :param str|unicode queue_name: The name of the queue to declare.

    """
    LOGGER.info('Declaring queue %s', queue_name)
    self._channel.queue_declare(self.on_queue_declareok, queue_name)

  def on_queue_declareok(self, method_frame):
    """Method invoked by pika when the Queue.Declare RPC call made in
    setup_queue has completed. In this method we will bind the queue
    and exchange together with the routing key by issuing the Queue.Bind
    RPC command. When this command is complete, the on_bindok method will
    be invoked by pika.

    :param pika.frame.Method method_frame: The Queue.DeclareOk frame

    """
    LOGGER.info('Binding %s to %s with %s',
          rc.valueExngAttr["exchange"], self.QUEUE, self.ROUTING_KEY)
    self._channel.queue_bind(self.on_bindok, self.QUEUE,
      rc.valueExngAttr["exchange"], self.ROUTING_KEY)

  def on_delivery_confirmation(self, method_frame):
    """Invoked by pika when RabbitMQ responds to a Basic.Publish RPC
    command, passing in either a Basic.Ack or Basic.Nack frame with
    the delivery tag of the message that was published. The delivery tag
    is an integer counter indicating the message number that was sent
    on the channel via Basic.Publish. Here we're just doing house keeping
    to keep track of stats and remove message numbers that we expect
    a delivery confirmation of from the list used to keep track of messages
    that are pending confirmation.

    :param pika.frame.Method method_frame: Basic.Ack or Basic.Nack frame

    """
    confirmation_type = method_frame.method.NAME.split('.')[1].lower()
    LOGGER.info('Received %s for delivery tag: %i',
          confirmation_type,
          method_frame.method.delivery_tag)
    if confirmation_type == 'ack':
      self._acked += 1
    elif confirmation_type == 'nack':
      self._nacked += 1
    self._deliveries.remove(method_frame.method.delivery_tag)
    LOGGER.info('Published %i messages, %i have yet to be confirmed, '
          '%i were acked and %i were nacked',
          self._message_number, len(self._deliveries),
          self._acked, self._nacked)

  def enable_delivery_confirmations(self):
    """Send the Confirm.Select RPC method to RabbitMQ to enable delivery
    confirmations on the channel. The only way to turn this off is to close
    the channel and create a new one.

    When the message is confirmed from RabbitMQ, the
    on_delivery_confirmation method will be invoked passing in a Basic.Ack
    or Basic.Nack method from RabbitMQ that will indicate which messages it
    is confirming or rejecting.

    """
    LOGGER.info('Issuing Confirm.Select RPC command')
    self._channel.confirm_delivery(self.on_delivery_confirmation)

  def publish_message(self):
    """If the class is not stopping, publish a message to RabbitMQ,
    appending a list of deliveries with the message number that was sent.
    This list will be used to check for delivery confirmations in the
    on_delivery_confirmations method.

    Once the message has been sent, schedule another message to be sent.
    The main reason I put scheduling in was just so you can get a good idea
    of how the process is flowing by slowing down and speeding up the
    delivery intervals by changing the PUBLISH_INTERVAL constant in the
    class.

    """
    if self._stopping:
      return

    message = 'The current epoch value is %i' % time.time()
    properties = pika.BasicProperties(app_id='example-publisher',
                      content_type='text/plain')

    self._channel.basic_publish(rc.valueExngAttr["exchange"], self.ROUTING_KEY,
                  message, properties)
    self._message_number += 1
    self._deliveries.append(self._message_number)
    LOGGER.info('Published message # %i', self._message_number)
    self.schedule_next_message()

  def schedule_next_message(self):
    """If we are not closing our connection to RabbitMQ, schedule another
    message to be delivered in PUBLISH_INTERVAL seconds.

    """
    if self._stopping:
      return
    LOGGER.info('Scheduling next message for %0.1f ms',
          self.PUBLISH_INTERVAL)
    self._connection.add_timeout(self.PUBLISH_INTERVAL,
                   self.publish_message)

  def start_publishing(self):
    """This method will enable delivery confirmations and schedule the
    first message to be sent to RabbitMQ

    """
    LOGGER.info('Issuing consumer related RPC commands')
    self.enable_delivery_confirmations()
    self.schedule_next_message()

  def on_bindok(self, unused_frame):
    """This method is invoked by pika when it receives the Queue.BindOk
    response from RabbitMQ. Since we know we're now setup and bound, it's
    time to start publishing."""
    LOGGER.info('Queue bound')
    self.start_publishing()

  def close_channel(self):
    """Invoke this command to close the channel with RabbitMQ by sending
    the Channel.Close RPC command.

    """
    LOGGER.info('Closing the channel')
    self._channel.close()

  def open_channel(self):
    """This method will open a new channel with RabbitMQ by issuing the
    Channel.Open RPC command. When RabbitMQ confirms the channel is open
    by sending the Channel.OpenOK RPC reply, the on_channel_open method
    will be invoked.

    """
    LOGGER.info('Creating a new channel')
    self._connection.channel(on_open_callback=self.on_channel_open)
Exemplo n.º 26
0
class PikaClient(object):

    def __init__(self, config, app=None):
        # Connection params
        self.host = config['host'] or 'localhost'
        self.port = config['port'] or '5672'
        self.vhost = config['vhost'] or '/'
        self.user = config['user'] or 'guest'
        self.passwd = config['passwd'] or 'guest'
        self.exchange = config['exchange'] or 'myx'
        self.queue_name = config['queue_name'] or 'tornado-test-%i' \
            % os.getpid()
        self.routing_key = config['routing_key'] or 'tornado.*'

        # Default values
        self.connected = False
        self.connecting = False
        self.connection = None
        self.channel = None

        self.app = app

        # Set our pika.log options
        pika.log.setup(color=True)

        # A place for us to keep messages sent to us by Rabbitmq
        self.messages = list()

        # A place for us to put pending messages while we're waiting to connect
        self.pending = list()

        self.connect()

    def connect(self):
        if self.connecting:
            pika.log.info('PikaClient: Already connecting to RabbitMQ')
            return
        pika.log.info('PikaClient: Connecting to RabbitMQ on %s:%i' \
            % (self.host, self.port))
        self.connecting = True

        credentials = pika.PlainCredentials(self.user, self.passwd)

        param = pika.ConnectionParameters(host=self.host, port=self.port,
            virtual_host=self.vhost, credentials=credentials)

        srs = SimpleReconnectionStrategy()

        logging.debug('Events: Connecting to AMQP Broker: %s:%i' % (self.host,
            self.port))

        # from pika.adapters import SelectConnection
        # connection = SelectConnection(parameters, on_connected)
        self.connection = TornadoConnection(param, reconnection_strategy=srs,
            on_open_callback=self.on_connected)

        self.connection.add_on_close_callback(self.on_closed)

    def on_connected(self, connection):
        pika.log.info('PikaClient: Connected to RabbitMQ on %s:%i' \
            % (self.host, self.port))

        self.connected = True
        self.connection = connection
        self.connection.channel(self.on_channel_open)

    def on_channel_open(self, channel):
        pika.log.info('PikaClient: Channel Open, Declaring Exchange %s' \
            % self.exchange)

        self.channel = channel
        self.channel.exchange_declare(exchange=self.exchange,
                                      type="direct",
                                      auto_delete=True,
                                      durable=False,
                                      callback=self.on_exchange_declared)

    def on_exchange_declared(self, frame):
        pika.log.info('PikaClient: Exchange Declared, Declaring Queue %s' \
            % self.queue_name)
        self.channel.queue_declare(queue=self.queue_name,
                                   auto_delete=True,
                                   durable=False,
                                   exclusive=False,
                                   callback=self.on_queue_declared)

    def on_queue_declared(self, frame):
        pika.log.info('PikaClient: Queue Declared, Binding Queue')
        self.channel.queue_bind(exchange=self.exchange,
                                queue=self.queue_name,
                                routing_key=self.routing_key,
                                callback=self.on_queue_bound)

    def on_queue_bound(self, frame):
        pika.log.info('PikaClient: Queue Bound, Issuing Basic Consume')
        self.channel.basic_consume(consumer_callback=self.on_message,
                                   queue=self.queue_name,
                                   no_ack=True)
        # Send any messages pending
        for properties, body in self.pending:
            self.channel.basic_publish(exchange=self.exchange,
                                       routing_key=self.routing_key,
                                       body=body,
                                       properties=properties)

    def on_basic_cancel(self, frame):
        pika.log.info('PikaClient: Basic Cancel Ok')
        # If we don't have any more consumer processes running close
        self.connection.close()

    def on_closed(self, connection):
        # We've closed our pika connection so stop the demo
        tornado.ioloop.IOLoop.instance().stop()

    def on_message(self, channel, method, header, body):
        pika.log.info('PikaCient: Message received: %s delivery tag #%i: %s' \
           % (header.content_type, method.delivery_tag, body))

        # Append it to our messages list
        self.messages.append(body)

        self.app.dispatcher.notifyCallbacks(body)

    def get_messages(self):
        # Get the messages to return, then empty the list
        output = self.messages
        self.messages = list()
        return output

    def publish(self, msg):
        # Build a message to publish to RabbitMQ
        #body = '%.8f: Request from %s [%s]' % \
        #       (tornado_request._start_time,
        #        tornado_request.remote_ip,
        #        tornado_request.headers.get("User-Agent"))

        # Send the message
        properties = pika.BasicProperties(content_type="text/plain",
                                          delivery_mode=1)
        self.channel.basic_publish(exchange=self.exchange,
                                   routing_key=self.routing_key,
                                   #body='Message: %s - %s' % (msg, body),
                                   body='Message: %s' % msg,
                                   properties=properties)
Exemplo n.º 27
0
class PikaClient(object):

    def __init__(self):
        # Construct a queue name we'll use for this instance only
              
        #Giving unique queue for each consumer under a channel.
        self.queue_name = "/4EAqhJ1FaJuuGc07qS3KwZZamZypZDMVfpx/TIO/CaqNjhuV7+36tEUCIdzborOFqtcxSBvgjW0Ywe+s0Sj9Q6+t+TfRk44kxZpw8Eyg8H6LcKbiUzWmZqMIfdsTUfqRWLaAj2UN2ZVHf6hmDyyOEbEGTl6t0qUXXNJDMaSlBLVAqsDAQAB"#"queue-%s" % (id(self),)
    
        # Default values
        self.connected = False
        self.connecting = False
        self.connection = None
        self.channel = None
    
        #Webscoket object.
        self.websocket = None
    
        
    def connect(self):
    
        if self.connecting:
            pika.log.info('PikaClient: Already connecting to RabbitMQ')
            return
        
        pika.log.info('PikaClient: Connecting to RabbitMQ on localhost:5672, Object: %s' % (self,))
        
        self.connecting = True

        credentials = pika.PlainCredentials('guest', 'guest')
        param = pika.ConnectionParameters(host='pepperjack.stanford.edu',
                                          port=5672,
                                          virtual_host="/",
                                          credentials=credentials)
        self.connection = TornadoConnection(param,
                                            on_open_callback=self.on_connected)
        
        #Currently this will close tornado ioloop.
        #self.connection.add_on_close_callback(self.on_closed)

    def on_connected(self, connection):
        pika.log.info('PikaClient: Connected to RabbitMQ on localhost:5672')
        self.connected = True
        self.connection = connection
        self.connection.channel(self.on_channel_open)

    def on_channel_open(self, channel):
        pika.log.info('PikaClient: Channel Open, Declaring Exchange, Channel ID: %s' % (channel,))
        self.channel = channel
        
        self.channel.exchange_declare(exchange='tornado',
                                      type="direct",
                                      auto_delete=True,
                                      durable=False,
                                      callback=self.on_exchange_declared)

    def on_exchange_declared(self, frame):
        pika.log.info('PikaClient: Exchange Declared, Declaring Queue')
        pika.log.info(self.queue_name)
        self.channel.queue_declare(auto_delete=False,
                       queue = self.queue_name,
                            durable=True,
                           exclusive=False,
                           callback=self.on_queue_declared)
           
       

    def on_queue_declared(self, frame):
    
        pika.log.info('PikaClient: Queue Declared, Binding Queue')
        self.channel.queue_bind(exchange='tornado',
                                queue=self.queue_name,
                                routing_key='tornado.*',
                                callback=self.on_queue_bound)
    
    def on_queue_bound(self, frame):
        pika.log.info('PikaClient: Queue Bound, Issuing Basic Consume')
        self.channel.basic_consume(consumer_callback=self.on_pika_message,
                                   queue=self.queue_name,
                                   no_ack=True)
        
    def on_pika_message(self, channel, method, header, body):
        pika.log.info('PikaCient: Message receive, delivery tag #%i' % \
                     method.delivery_tag)
     
        #Send the Cosumed message via Websocket to browser.
        self.websocket.write_message(base64.encodestring(body))
        
        

    def on_basic_cancel(self, frame):
        pika.log.info('PikaClient: Basic Cancel Ok')
        # If we don't have any more consumer processes running close
        self.connection.close()

    def on_closed(self, connection):
        # We've closed our pika connection so stop the demo
        tornado.ioloop.IOLoop.instance().stop()
    
    
    def sample_message(self, ws_msg):
        #Publish the message from Websocket to RabbitMQ
        properties = pika.BasicProperties(content_type="text/plain",delivery_mode=1)
        
        self.channel.basic_publish(exchange='tornado',
                                   routing_key='tornado.*',
                                   body = ws_msg,
                                   properties=properties)
Exemplo n.º 28
0
class PikaClient(object):
    def __init__(self):

        # Construct a queue name we'll use for this instance only

        #Giving unique queue for each consumer under a channel.
        self.queue_name = "queue-%s" % (id(self), )
        # Default values
        self.connected = False
        self.connecting = False
        self.connection = None
        self.channel = None

        #Webscoket object.
        self.websocket = None

    def connect(self):

        if self.connecting:
            print('PikaClient: Already connecting to RabbitMQ')
            return

        print(
            'PikaClient: Connecting to RabbitMQ on localhost:5672, Object: %s'
            % (self, ))

        self.connecting = True

        credentials = pika.PlainCredentials('guest', 'guest')
        param = pika.ConnectionParameters(host='localhost',
                                          port=5672,
                                          virtual_host="/",
                                          credentials=credentials)
        self.connection = TornadoConnection(param,
                                            on_open_callback=self.on_connected)

    def on_connected(self, connection):
        print('PikaClient: Connected to RabbitMQ on localhost:5672')
        self.connected = True
        self.connection = connection
        self.connection.channel(self.on_channel_open)

    def on_channel_open(self, channel):

        print('PikaClient: Channel Open, Declaring Exchange, Channel ID: %s' %
              (channel, ))
        self.channel = channel

        self.channel.exchange_declare(exchange='tornado',
                                      exchange_type="direct",
                                      auto_delete=True,
                                      durable=False,
                                      callback=self.on_exchange_declared)

    def on_exchange_declared(self, frame):
        print('PikaClient: Exchange Declared, Declaring Queue')
        self.channel.queue_declare(auto_delete=True,
                                   queue=self.queue_name,
                                   durable=False,
                                   exclusive=True,
                                   callback=self.on_queue_declared)

    def on_queue_declared(self, frame):

        print('PikaClient: Queue Declared, Binding Queue')
        self.channel.queue_bind(exchange='tornado',
                                queue=self.queue_name,
                                routing_key='tornado.*',
                                callback=self.on_queue_bound)

    def on_queue_bound(self, frame):
        print('PikaClient: Queue Bound, Issuing Basic Consume')
        self.channel.basic_consume(consumer_callback=self.on_pika_message,
                                   queue=self.queue_name,
                                   no_ack=True)

    def on_pika_message(self, channel, method, header, body):
        print('PikaCient: Message receive, delivery tag #%i' %
              method.delivery_tag)

        #Send the Cosumed message via Websocket to browser.
        self.websocket.write_message(body)

    def on_basic_cancel(self, frame):
        print('PikaClient: Basic Cancel Ok')
        # If we don't have any more consumer processes running close
        self.connection.close()

    def on_closed(self, connection):
        # We've closed our pika connection so stop the web chat
        tornado.ioloop.IOLoop.instance().stop()

    def chat_message(self, ws_msg):
        #Publish the message from Websocket to RabbitMQ
        properties = pika.BasicProperties(content_type="text/plain",
                                          delivery_mode=1)

        self.channel.basic_publish(exchange='tornado',
                                   routing_key='tornado.*',
                                   body=ws_msg,
                                   properties=properties)
Exemplo n.º 29
0
class PikaClient(object):

    def __init__(self, chat_id):

        # Construct a queue name we'll use for this instance only

        # Giving unique queue for each consumer under a channel.
        self.queue_name = "queue-%s" % (id(self),)
        # Default values
        self.connected = False
        self.connecting = False
        self.connection = None
        self.channel = None
        self.chat_id = chat_id

        # Webscoket object.
        self.websocket = None

    def connect(self):

        if self.connecting:
                print('PikaClient: Already connecting to RabbitMQ')
                return

        print('PikaClient: Connecting to RabbitMQ on localhost:5672, Object: %s' % (self,))

        self.connecting = True

        credentials = pika.PlainCredentials('guest', 'guest')
        param = pika.ConnectionParameters(host='localhost',
                                          port=5672,
                                          virtual_host="/",
                                          credentials=credentials)
        self.connection = TornadoConnection(param,
                                            on_open_callback=self.on_connected)

        # Currently this will close tornado ioloop.
        # self.connection.add_on_close_callback(self.on_closed)

    def on_connected(self, connection):
        print('PikaClient: Connected to RabbitMQ on localhost:5672')
        self.connected = True
        self.connection = connection
        self.connection.channel(self.on_channel_open)

    def on_channel_open(self, channel):

        print('PikaClient: Channel Open, Declaring Exchange, Channel ID: %s' %
              (channel,))
        self.channel = channel

        self.channel.exchange_declare(exchange='chat',
                                      type="direct",
                                      callback=self.on_exchange_declared)

    def on_exchange_declared(self, frame):
        print('PikaClient: Exchange Declared, Declaring Queue')
        self.channel.queue_declare(queue=self.queue_name,
                                   exclusive=True,
                                   callback=self.on_queue_declared)

    def on_queue_declared(self, frame):

        print('PikaClient: Queue Declared, Binding Queue')
        self.channel.queue_bind(exchange='chat',
                                queue=self.queue_name,
                                routing_key=self.chat_id,
                                callback=self.on_queue_bound)

    def on_queue_bound(self, frame):
        print('PikaClient: Queue Bound, Issuing Basic Consume')
        self.channel.basic_consume(consumer_callback=self.on_pika_message,
                                   queue=self.queue_name,
                                   no_ack=True)

    def on_pika_message(self, channel, method, header, body):
        print('PikaCient: Message receive, delivery tag #%i' %
              method.delivery_tag)

        # Send the Cosumed message via Websocket to browser.
        self.websocket.write_message(body.decode('utf8'))

    def on_basic_cancel(self, frame):
        print('PikaClient: Basic Cancel Ok')
        # If we don't have any more consumer processes running close
        self.connection.close()

    def on_closed(self, connection):
        # We've closed our pika connection so stop the demo
        tornado.ioloop.IOLoop.instance().stop()
Exemplo n.º 30
0
class PikaClient(object):

    def __init__(self, ):
        # Default values
        self.connected = False
        self.connecting = False
        self.connection = None
        self.channel = None
        self.main_future = Future()

        # A place for us to keep messages sent to us by Rabbitmq
        self.messages = list()

    def _make_response(code, message):
        # TODO:
        pass

    def _get_callback_with_future(self, callback, future):

        def _callback(*args, **kwargs):
            res = callback(*args, **kwargs)
            future.set_result(res)

        return _callback

    # -----------------------------------------------------
    # Connection functions
    # -----------------------------------------------------

    # TODO: make this async
    def connect(self):
        if self.connecting:
            logging.info('Already connecting to RabbitMQ')
            return
        logging.info('Connecting to RabbitMQ on localhost:5672')
        self.connecting = True

        credentials = pika.PlainCredentials('guest', 'guest')
        param = pika.ConnectionParameters(host='localhost',
                                          port=5672,
                                          virtual_host="/",
                                          credentials=credentials)
        self.connection = TornadoConnection(param,
                                            on_open_callback=self.on_connected)
        self.connection.add_on_close_callback(self.on_closed)

    def on_connected(self, connection):
        logging.info('Connected to RabbitMQ on localhost:5672')
        self.connected = True
        self.connection = connection

        self._init_channel()

    def on_closed(self, connection):
        # We've closed our pika connection so stop the demo
        tornado.ioloop.IOLoop.instance().stop()

    # -----------------------------------------------------
    # Channel functions
    # -----------------------------------------------------

    @property
    def channel(self):
        if self._channel is None or not self._channel.is_open:
            self._init_channel()

        return self._channel

    def _init_channel(self):
        self.connection.channel(self.on_channel_open)


    def on_channel_close(self, channel, reply_code, reply_text):
        logging.info('Channel closed, reply_code=%s, reply_text=%s', reply_code,
                     reply_text)
        self.main_future.set_result(reply_code)

    def on_channel_open(self, channel):
        logging.info('Channel Open')
        self._channel = channel
        self._channel.add_on_close_callback(self.on_channel_close)

    # -----------------------------------------------------
    # Queue functions
    # -----------------------------------------------------

    @async_func
    def queue_declare(self, future, queue):
        logging.info('Declaring Queue')

        cb = self._get_callback_with_future(self._on_queue_declare_ok, future)
        self.channel.queue_declare(queue=queue,
                                   durable=True,
                                   callback=cb)

    def _on_queue_declare_ok(self, frame):
        logging.info('Queue Declared')
        return frame

    @async_func
    def queue_bind(self, future, exchange, queue, routing_key):
        logging.info('Binding Queue %s to Exchange %s', queue, exchange)

        cb = self._get_callback_with_future(self.on_queue_bind_ok, future)
        self.channel.queue_bind(exchange=exchange, queue=queue,
                                routing_key=routing_key,
                                callback=cb)

    def on_queue_bind_ok(self, frame):
        logging.info('Queue Bound')
        return frame

    def get_messages():
        self.channel.basic_consume(consumer_callback=self.on_pika_message,
                                   queue=self.queue_name,
                                   no_ack=True)

    def on_pika_message(self, channel, method, header, body):
        logging.info('Message receive, delivery tag #%i' % \
                     method.delivery_tag)
        # Append it to our messages list
        self.messages.append(body)

    def on_basic_cancel(self, frame):
        logging.info('Basic Cancel Ok')
        # If we don't have any more consumer processes running close
        self.connection.close()

    def publish_message(self, exchange, queue):
        # Build a message to publish to RabbitMQ
        body = '%.8f: Request from %s [%s]' % \
               (tornado_request._start_time,
                tornado_request.remote_ip,
                tornado_request.headers.get("User-Agent"))

        # Send the message
        properties = pika.BasicProperties(content_type="text/plain",
                                          delivery_mode=1)
        self.channel.basic_publish(exchange='tornado',
                                   routing_key='tornado.*',
                                   body=body,
                                   properties=properties)
Exemplo n.º 31
0
class Dealer(object):
    def __init__(self, exchange, host, port):
        self.exchange = exchange
        self.host = host
        self.port = port
        self.room_list = {}

    def init_database(self):
        database.init_database()

        info = DealerInfo.find(exchange=self.exchange)

        if not info:
            info = DealerInfo.new(self.exchange)
        else:
            print "WARNING, dealer %s already in database" % self.exchange

        info.rooms = 0
        self.info = info

    def on_queue_bound(self, frame):
        self.channel.basic_consume(consumer_callback=self.on_message,
                                   queue=self.queue_name,
                                   no_ack=True)

    def on_queue_declared(self, frame):
        self.queue_name = frame.method.queue
        self.channel.queue_bind(exchange=self.exchange,
                                queue=self.queue_name,
                                routing_key='dealer',
                                callback=self.on_queue_bound)

    def on_exchange_declared(self, frame):
        self.channel.queue_declare(auto_delete=True,
                                   durable=False,
                                   exclusive=False,
                                   callback=self.on_queue_declared)

    def on_channel_open(self, channel):
        self.channel = channel
        self.channel.exchange_declare(exchange=self.exchange,
                                      type='topic',
                                      auto_delete=True,
                                      durable=False,
                                      callback=self.on_exchange_declared)

    def on_connected(self, connection):
        connection.channel(self.on_channel_open)

    def start(self):
        credentials = pika.PlainCredentials('guest', 'guest')
        param = pika.ConnectionParameters(self.host,
                                          port=self.port,
                                          virtual_host="/",
                                          credentials=credentials)

        self.connection = TornadoConnection(param,
                                            on_open_callback=self.on_connected)
        self.connection.set_backpressure_multiplier(100000)

    def cmd_action(self, args):
        print "action in dealer %d" % args["action"]
        if args["room_id"] in self.room_list:
            current_room = self.room_list[args["room_id"]]
            current_room.user_action(args)

    def cmd_chat(self, args):
        print args
        room = self.room_list[args['room']]
        room.chat(args['user'], args['seat'], args['content'])

    def cmd_sit(self, args):
        print "sit received"
        source = args['source']
        private_key = args['private_key']
        stake = args['stake']
        user = User.find(_id=args['user_id'])
        print args['user_id']
        current_room = self.room_list[args["room_id"]]
        (status, msg) = current_room.sit(user, int(args["seat"]), source,
                                         private_key, stake)

        if status:
            message = {"status": "success"}
        else:
            message = {"status": "failed", "msg": msg}
        self.channel.basic_publish(exchange=self.exchange,
                                   routing_key=source,
                                   body=json.dumps(message))

    def broadcast(self, routing_key, msg):
        self.channel.basic_publish(exchange=self.exchange,
                                   routing_key=routing_key,
                                   body=json.dumps(msg))

    def cmd_enter(self, args):
        routing_key = args['source']
        user_id = args['user_id']
        if args['room_id'] not in self.room_list:
            #self.cmd_create_room(args)
            message = {'status': 'failed'}
        else:
            current_room = self.room_list[args["room_id"]]

            message = {
                'status': 'success',
                "room": current_room.to_listener(user_id)
            }

        self.channel.basic_publish(exchange=self.exchange,
                                   routing_key=routing_key,
                                   body=json.dumps(message))
        #current_room.resend_last_next_message()

    def cmd_create_room(self, args):
        print "creating room"

        blind = int(args["blind"])
        max_stake = int(args["max_stake"])
        min_stake = int(args["min_stake"])
        max_player = int(args["max_player"])
        routing_key = args['source']
        roomType = int(args["roomType"])

        newRoom = Room.new(self.exchange, blind, max_player, max_stake,
                           min_stake, roomType)

        self.room_list[newRoom.id] = GameRoom(newRoom, args["user_id"], self,
                                              max_player, blind, min_stake,
                                              max_stake)
        print newRoom
        message = {"room_id": newRoom.id}

        self.channel.basic_publish(exchange=self.exchange,
                                   routing_key=routing_key,
                                   body=json.dumps(message))

        self.info.rooms += 1

    def on_message(self, channel, method, header, body):
        print "ON_MESSAGE!"
        obj = json.loads(body)
        print body
        method = getattr(self, "cmd_" + obj['method'])
        method(obj)

    def close(self):
        self.connection.close()

    def handle_init_file(self, fname, isDebug):
        info = Room.find_all(exchange=self.exchange)
        for room in info:
            room.remove()

    #	if os.path.isfile(fname):
        print len(fname)
        print os.getcwd()
        with open(fname) as f:
            for line in f:
                if line[0] == '#':
                    continue

                (roomType, blind, max_stake, min_stake,
                 max_player) = (int(x) for x in line.strip().split(','))

                newRoom = Room.new(self.exchange, blind, max_player, max_stake,
                                   min_stake, roomType)
                self.room_list[newRoom.id] = GameRoom(newRoom, 1, self,
                                                      max_player, blind,
                                                      min_stake, max_stake)
                self.info.rooms += 1
                print newRoom
Exemplo n.º 32
0
class PikaClient(object):
    def __init__(self, settings):
        self.settings = settings
        # Construct a queue name we'll use for this instance only
        self.queue_name = "tornado-test-%i" % os.getpid()

        # Default values
        self.connected = False
        self.connecting = False
        self.connection = None
        self.channel = None

        # A place for us to keep messages sent to us by Rabbitmq
        self.messages = list()

        # A place for us to put pending messages while we're waiting to connect
        self.pending = list()

    def connect(self):
        if self.connecting:
            pika.log.info("PikaClient: Already connecting to RabbitMQ")
            return
        pika.log.info("PikaClient: Connecting to RabbitMQ on localhost:5672")
        self.connecting = True
        credentials = pika.PlainCredentials(self.settings.user, self.settings.password)
        param = pika.ConnectionParameters(
            host=self.settings.host,
            port=self.settings.port,
            virtual_host=self.settings.virtual_host,
            credentials=credentials,
        )
        self.connection = TornadoConnection(param, on_open_callback=self.on_connected)
        self.connection.add_on_close_callback(self.on_closed)

    def on_connected(self, connection):
        pika.log.info("PikaClient: Connected to RabbitMQ on localhost:5672")
        self.connected = True
        self.connection = connection
        self.connection.channel(self.on_channel_open)

    def on_channel_open(self, channel):
        pika.log.info("PikaClient: Channel Open, Declaring Exchange")
        self.channel = channel
        self.channel.exchange_declare(
            exchange="tornado", type="direct", auto_delete=True, durable=False, callback=self.on_exchange_declared
        )

    def on_exchange_declared(self, frame):
        pika.log.info("PikaClient: Exchange Declared, Declaring Queue")
        self.channel.queue_declare(
            queue=self.queue_name, auto_delete=True, durable=False, exclusive=False, callback=self.on_queue_declared
        )

    def on_queue_declared(self, frame):
        pika.log.info("PikaClient: Queue Declared, Binding Queue")
        self.channel.queue_bind(
            exchange="tornado", queue=self.queue_name, routing_key="tornado.*", callback=self.on_queue_bound
        )

    def on_queue_bound(self, frame):
        pika.log.info("PikaClient: Queue Bound, Issuing Basic Consume")
        self.channel.basic_consume(consumer_callback=self.on_pika_message, queue=self.queue_name, no_ack=True)
        # Send any messages pending
        for properties, body in self.pending:
            self.channel.basic_publish(exchange="tornado", routing_key="tornado.*", body=body, properties=properties)

    def on_pika_message(self, channel, method, header, body):
        pika.log.info("PikaCient: Message receive, delivery tag #%i" % method.delivery_tag)
        # Append it to our messages list
        self.messages.append(body)

        # ==============================================================================
        self.callback(body)  # 3.use external callback(self.send) on here

    def cb(self, callback):  # 1. use app.pika.cb for setting external callback function
        self.callback = callback  # 2.assign external callback to self.callback

    # ==============================================================================

    def on_basic_cancel(self, frame):
        pika.log.info("PikaClient: Basic Cancel Ok")
        # If we don't have any more consumer processes running close
        self.connection.close()

    def on_closed(self, connection):
        #  TODO:We've closed our pika connection so stop the demo
        tornado.ioloop.IOLoop.instance().stop()

    def sample_message(self, msg):
        # Build a message to publish to RabbitMQ
        body = msg

        # Send the message
        properties = pika.BasicProperties(content_type="text/plain", delivery_mode=1)

        self.channel.basic_publish(exchange="tornado", routing_key="tornado.*", body=body, properties=properties)

    def get_messages(self):
        # Get the messages to return, then empty the list
        output = self.messages
        self.messages = list()
        return output
Exemplo n.º 33
0
class PikaClient(object):
    def __init__(self, config, exchanges):
        self.connecting = False
        self.connection = None
        self.channel = None
        self.config = config
        self.exchanges = exchanges

    def connect(self):
        if self.connecting:
            return
        self.connecting = True
        host = self.config.get('host')
        port = 5671 if self.config.get('amqps') else 5672
        scheme = 'amqps' if self.config.get('amqps') else 'amqp'
        virtual_host = urllib.parse.quote(self.config.get('vhost'), safe='')
        user = self.config.get('user')
        pw = self.config.get('pw')
        heartbeat = self.config.get('heartbeat') if self.config.get(
            'heartbeat') else 0
        params = pika.URLParameters(
            f"{scheme}://{user}:{pw}@{host}:{port}/{virtual_host}?heartbeat={heartbeat}"
        )
        self.connection = TornadoConnection(params)
        self.connection.add_on_open_callback(self.on_connect)
        self.connection.add_on_close_callback(self.on_closed)
        return

    def on_connect(self, connection):
        self.connection = connection
        self.channel = self.connection.channel(
            on_open_callback=self.on_channel_open)
        return

    def on_channel_open(self, channel):
        for backend, config in self.exchanges.items():
            ex_name = config.get('exchange')
            channel.exchange_declare(ex_name,
                                     exchange_type='topic',
                                     durable=True)
            logging.info(f'rabbitmq exchange: {ex_name} declared')
        return

    def on_basic_cancel(self, frame):
        self.connection.close()

    def on_closed(self, connection):
        tornado.ioloop.IOLoop.instance().stop()

    def publish_message(self,
                        exchange=None,
                        routing_key=None,
                        method=None,
                        uri=None,
                        version=None,
                        data=None,
                        persistent=True):
        """
        Publilsh a message to an exchange.

        Parameters
        ----------
        exchange: str, exchange name
        routing_key: str, routing key for topic exchange
        method: str, HTTP method
        uri: str, HTTP request URI
        version: str, e.g. v1
        data: dict
        persistent: bool, default True
            tell rabbitmq to persist messages to disk, or not

        """
        data = {'method': method, 'uri': uri, 'version': version, 'data': data}
        message = json.dumps(data)
        delivery_mode = 2 if persistent else 1
        self.channel.basic_publish(exchange=exchange,
                                   routing_key=routing_key,
                                   body=message,
                                   properties=pika.BasicProperties(
                                       content_type='application/json',
                                       delivery_mode=delivery_mode))
        return
class PikaPublisher(object):

    def __init__(self, amqp_parameters, exchange, exchange_type, queue, routing_key):
        self._exchange = exchange
        self._exchange_type = exchange_type
        self._queue = queue
        self._routing_key = routing_key

        self._connection = None
        self._channel = None
        self._deliveries = []
        self._acked = 0
        self._nacked = 0
        self._message_number = 0
        self._stopping = False
        self._params = amqp_parameters
        self._closing = False

        logging.basicConfig(level=logging.INFO, format=LOG_FORMAT)

    def connect(self):
        self._connection = TornadoConnection(self._params, self.on_connection_open, stop_ioloop_on_close=False)

        LOGGER.info('Adding connection close callback')
        self._connection.add_on_close_callback(self.on_connection_closed)
        return self._connection

    def close_connection(self):
        LOGGER.info('Closing connection')
        self._closing = True
        self._connection.close()

    def on_connection_closed(self, connection, reply_code, reply_text):
        self._channel = None
        if self._closing:
            self._connection.ioloop.stop()
        else:
            LOGGER.warning('Connection closed, reopening in 5 seconds: (%s) %s',
                           reply_code, reply_text)
            self._connection.add_timeout(5, self.reconnect)

    def on_connection_open(self, unused_connection):
        LOGGER.info('Connection opened')
        self.open_channel()

    def reconnect(self):
        # This is the old connection IOLoop instance, stop its ioloop
        self._connection.ioloop.stop()

        # Create a new connection
        self._connection = self.connect()

        # There is now a new connection, needs a new ioloop to run
        self._connection.ioloop.start()

    def add_on_channel_close_callback(self):
        LOGGER.info('Adding channel close callback')
        self._channel.add_on_close_callback(self.on_channel_closed)

    def on_channel_closed(self, channel, reply_code, reply_text):
        LOGGER.warning('Channel was closed: (%s) %s', reply_code, reply_text)
        if not self._closing:
            self._connection.close()

    def on_channel_open(self, channel):
        LOGGER.info('Channel opened')
        self._channel = channel
        self.add_on_channel_close_callback()
        self.setup_exchange(self._exchange)

    def setup_exchange(self, exchange_name):
        LOGGER.info('Declaring exchange %s', exchange_name)
        self._channel.exchange_declare(self.on_exchange_declareok,
                                       exchange_name,
                                       self._exchange_type, durable=True)

    def on_exchange_declareok(self, unused_frame):
        LOGGER.info('Exchange declared')
        self.setup_queue(self._queue)

    def setup_queue(self, queue_name):
        LOGGER.info('Declaring queue %s', queue_name)
        self._channel.queue_declare(self.on_queue_declareok, queue_name, durable = True)

    def on_queue_declareok(self, method_frame):
        LOGGER.info('Binding %s to %s with %s',
                    self._exchange, self._queue, self._routing_key)
        self._channel.queue_bind(self.on_bindok, self._queue,
                                 self._exchange, self._routing_key)

    def on_delivery_confirmation(self, method_frame):
        confirmation_type = method_frame.method.NAME.split('.')[1].lower()
        LOGGER.info('Received %s for delivery tag: %i',
                    confirmation_type,
                    method_frame.method.delivery_tag)
        if confirmation_type == 'ack':
            self._acked += 1
        elif confirmation_type == 'nack':
            self._nacked += 1
        self._deliveries.remove(method_frame.method.delivery_tag)
        LOGGER.info('Published %i messages, %i have yet to be confirmed, '
                    '%i were acked and %i were nacked',
                    self._message_number, len(self._deliveries),
                    self._acked, self._nacked)

    def enable_delivery_confirmations(self):
        LOGGER.info('Issuing Confirm.Select RPC command')
        self._channel.confirm_delivery(self.on_delivery_confirmation)

    def publish_message(self, message):
        if self._stopping:
            return

        properties = pika.BasicProperties(app_id='example-publisher',
                                          content_type='application/json',
                                          delivery_mode = 2,
                                          headers=message)

        self._channel.basic_publish(self._exchange, self._routing_key,
                                    json.dumps(message, ensure_ascii=False),
                                    properties)
        self._message_number += 1
        self._deliveries.append(self._message_number)
        LOGGER.info('Published message # %i', self._message_number)

    def on_bindok(self, unused_frame):
        LOGGER.info('Queue bound')

    def close_channel(self):
        LOGGER.info('Closing the channel')
        if self._channel:
            self._channel.close()

    def open_channel(self):
        LOGGER.info('Creating a new channel')
        self._connection.channel(on_open_callback=self.on_channel_open)

    def stop(self):
        LOGGER.info('Stopping')
        self._stopping = True
        self.close_channel()
        self.close_connection()
        self._connection.ioloop.start()
        LOGGER.info('Stopped')
Exemplo n.º 35
0
class PikaClient(object):
    tornado_callback = None
    _closing = False
    _connect_index = 0
    _connect_pull = None
    _one_respond_made = None
    _waiting_to_reconnect = 3
    _expire_reconnect = 15
    _last_reconnect_fail = None

    def __init__(self, logger,
                 queue_answer, queue_read, queue_create,
                 node_list):
        # Construct a queue name we'll use for this instance only
        self.queue_answer = queue_answer

        # Create queue for sending
        self.queue_read = queue_read
        self.queue_create = queue_create

        self.logger = logger
        self.connected = False
        self.connecting = False
        self.connection = None
        self.channel = None

        # A place for us to keep messages sent to us by Rabbitmq
        self.messages = list()
        # A place for us to put pending messages while we're waiting to connect
        self.pending = list()

        self._connect_pull = []
        for node in node_list:
            self._connect_pull.append(
                pika.ConnectionParameters(
                    host=node[0], port=int(node[1])))

    def connect(self):
        if self.connecting:
            self.logger.warning('Already connecting to RabbitMQ')
            return
        param = self._connect_pull[self._connect_index]
        self.logger.debug('Connecting to RabbitMQ on '
                          '{host}:{port}'.format(host=param.host,
                                                 port=param.port))
        self.connecting = True
        # TODO: add on_connection_error
        try:
            self.connection = TornadoConnection(
                param,
                on_open_callback=self.on_connected
            )
            self.connection.add_on_close_callback(self.on_closed)
        except AMQPConnectionError:
            self.reconnect()

    def on_connected(self, connection):
        self.logger.debug('Connected to RabbitMQ on: '
                          '{connection}'.format(connection=connection))
        self.connected = True
        self.connection = connection
        self.connection.channel(self.on_channel_open)

    def on_channel_open(self, channel):
        self.logger.debug('Channel Open, Declaring Exchange')
        self.channel = channel
        self.channel.exchange_declare(exchange='tornado',
                                      type='topic',
                                      durable=True,
                                      callback=self.on_exchange_declared)

    def on_exchange_declared(self, frame):
        self.logger.debug('Exchange Declared, Declaring Queue')
        self.channel.queue_declare(queue=self.queue_answer,
                                   durable=True,
                                   callback=self.on_queue_declared)
        self.channel.queue_declare(queue=self.queue_create,
                                   durable=True,
                                   callback=lambda frame:
                                       self.channel.queue_bind(
                                           exchange='tornado',
                                           queue=self.queue_create,
                                           routing_key=self.queue_create,
                                           callback=None))
        self.channel.queue_declare(queue=self.queue_read,
                                   durable=True,
                                   callback=lambda frame:
                                       self.channel.queue_bind(
                                           exchange='tornado',
                                           queue=self.queue_read,
                                           routing_key=self.queue_read,
                                           callback=None))

    def on_queue_declared(self, frame):
        self.logger.debug('Queue Declared, Binding Queue')
        self.channel.queue_bind(exchange='tornado',
                                queue=self.queue_answer,
                                callback=self.on_queue_bound)

    def on_queue_bound(self, frame):
        self.logger.debug('Queue Bound, Issuing Basic Consume')
        self.channel.basic_consume(consumer_callback=self.on_pika_message,
                                   queue=self.queue_answer,
                                   no_ack=True)

        # TODO: still not implemented
        # for properties, body in self.pending:
        #     self.logger.debug('Pending Message:'
        #                       ' %s | %s' % (properties, body))
        #     self.channel.basic_publish(exchange='tornado',
        #                                # TODO: save routing_key or
        #                                # it already in properties
        #                                routing_key='reading',
        #                                body=body,
        #                                properties=properties)

    def on_pika_message(self, channel, method, header, body):
        self.logger.debug('Message receive: '
                          'body: {body}'.format(method=method,
                                                header=header,
                                                body=body))
        if self.tornado_callback and not self._one_respond_made:
            self.messages.append(body)
            self.tornado_callback(self.get_messages())
            self._one_respond_made = True

    def on_basic_cancel(self, frame):
        self.logger.debug('Basic Cancel Ok')
        self.connection.close()

    def on_closed(self, *args):
        self.logger.warning('On closed. Try to reconnect...')
        self.reconnect()

    def reconnect(self):
        self.logger.warning('Fail to connect')
        if self._last_reconnect_fail:
            current_fail_time = datetime.datetime.now()
            fail_timedelta = current_fail_time - self._last_reconnect_fail
            self.logger.debug('Check reconnect expires, '
                              'timedelta: %s seconds' % fail_timedelta.seconds)
            if fail_timedelta.seconds >= self._expire_reconnect:
                self._closing = False
                self._connect_index = 0
                self._last_reconnect_fail = datetime.datetime.now()
                self.logger.debug('Reconnect time is expired, '
                                  'reset reconnect parameters')
        else:
            self.logger.warning('Set first fail reconnect time')
            self._last_reconnect_fail = datetime.datetime.now()

        self.connecting = False
        self.connected = False
        self.logger.warning('%s sec waiting...' % self._waiting_to_reconnect)
        time.sleep(self._waiting_to_reconnect)
        if not self._closing:
            self._connect_index += 1
            self.logger.warning('Try to reconnect to %s, try number %s' %
                                (self._connect_pull[self._connect_index],
                                 self._connect_index))
            if self._connect_index == len(self._connect_pull) - 1:
                self._closing = True
            self.connect()
        else:
            self.logger.warning('Closing. Stop trying')
            self.stop()

    def stop(self):
        self.logger.warning('STOP')
        self._closing = True
        tornado.ioloop.IOLoop.instance().stop()

    def sample_message(self, msg, routing_key, tornado_callback):
        self.logger.debug('Sample Message to %s' % routing_key)
        self.tornado_callback = tornado_callback
        properties = pika.BasicProperties(delivery_mode=1)

        self._one_respond_made = False
        self.channel.basic_publish(exchange='tornado',
                                   routing_key=routing_key,
                                   body=msg,
                                   properties=properties)

    def get_messages(self):
        output = self.messages
        self.messages = list()
        return output
Exemplo n.º 36
0
class PikaClient(object):
    def __init__(self):
        # Construct a queue name we'll use for this instance only

        #Giving unique queue for each consumer under a channel.
        self.queue_name = "/4EAqhJ1FaJuuGc07qS3KwZZamZypZDMVfpx/TIO/CaqNjhuV7+36tEUCIdzborOFqtcxSBvgjW0Ywe+s0Sj9Q6+t+TfRk44kxZpw8Eyg8H6LcKbiUzWmZqMIfdsTUfqRWLaAj2UN2ZVHf6hmDyyOEbEGTl6t0qUXXNJDMaSlBLVAqsDAQAB"  #"queue-%s" % (id(self),)

        # Default values
        self.connected = False
        self.connecting = False
        self.connection = None
        self.channel = None

        #Webscoket object.
        self.websocket = None

    def connect(self):

        if self.connecting:
            pika.log.info('PikaClient: Already connecting to RabbitMQ')
            return

        pika.log.info(
            'PikaClient: Connecting to RabbitMQ on localhost:5672, Object: %s'
            % (self, ))

        self.connecting = True

        credentials = pika.PlainCredentials('guest', 'guest')
        param = pika.ConnectionParameters(host='pepperjack.stanford.edu',
                                          port=5672,
                                          virtual_host="/",
                                          credentials=credentials)
        self.connection = TornadoConnection(param,
                                            on_open_callback=self.on_connected)

        #Currently this will close tornado ioloop.
        #self.connection.add_on_close_callback(self.on_closed)

    def on_connected(self, connection):
        pika.log.info('PikaClient: Connected to RabbitMQ on localhost:5672')
        self.connected = True
        self.connection = connection
        self.connection.channel(self.on_channel_open)

    def on_channel_open(self, channel):
        pika.log.info(
            'PikaClient: Channel Open, Declaring Exchange, Channel ID: %s' %
            (channel, ))
        self.channel = channel

        self.channel.exchange_declare(exchange='tornado',
                                      type="direct",
                                      auto_delete=True,
                                      durable=False,
                                      callback=self.on_exchange_declared)

    def on_exchange_declared(self, frame):
        pika.log.info('PikaClient: Exchange Declared, Declaring Queue')
        pika.log.info(self.queue_name)
        self.channel.queue_declare(auto_delete=False,
                                   queue=self.queue_name,
                                   durable=True,
                                   exclusive=False,
                                   callback=self.on_queue_declared)

    def on_queue_declared(self, frame):

        pika.log.info('PikaClient: Queue Declared, Binding Queue')
        self.channel.queue_bind(exchange='tornado',
                                queue=self.queue_name,
                                routing_key='tornado.*',
                                callback=self.on_queue_bound)

    def on_queue_bound(self, frame):
        pika.log.info('PikaClient: Queue Bound, Issuing Basic Consume')
        self.channel.basic_consume(consumer_callback=self.on_pika_message,
                                   queue=self.queue_name,
                                   no_ack=True)

    def on_pika_message(self, channel, method, header, body):
        pika.log.info('PikaCient: Message receive, delivery tag #%i' % \
                     method.delivery_tag)

        #Send the Cosumed message via Websocket to browser.
        self.websocket.write_message(base64.encodestring(body))

    def on_basic_cancel(self, frame):
        pika.log.info('PikaClient: Basic Cancel Ok')
        # If we don't have any more consumer processes running close
        self.connection.close()

    def on_closed(self, connection):
        # We've closed our pika connection so stop the demo
        tornado.ioloop.IOLoop.instance().stop()

    def sample_message(self, ws_msg):
        #Publish the message from Websocket to RabbitMQ
        properties = pika.BasicProperties(content_type="text/plain",
                                          delivery_mode=1)

        self.channel.basic_publish(exchange='tornado',
                                   routing_key='tornado.*',
                                   body=ws_msg,
                                   properties=properties)
Exemplo n.º 37
0
class CaculateWorker(object):
    REDIS_HASHMAP_KEY = os.environ.get("REDIS_HASHMAP_KEY")

    def __init__(self):
        rabbitmq_server = os.environ.get("RABBITMQ_SERVER")
        redis_server = os.environ.get("REDIS_SERVER")

        self.redis_client = redis.Redis(host=redis_server, port=6379, db=0)

        self.ioloop = tornado.ioloop.IOLoop.instance()
        self.connection = None
        self.channel = None

        self._delivery_tag = 0

        self.parameters = pika.ConnectionParameters(rabbitmq_server)

    @staticmethod
    def fibonacci(index):
        if index <= 1:
            return 1
        return CaculateWorker.fibonacci(index -
                                        1) + CaculateWorker.fibonacci(index -
                                                                      2)

    def cache_cacalate(self, index, value):
        self.redis_client.hset(CaculateWorker.REDIS_HASHMAP_KEY, index, value)

    def connect(self):
        try:
            self.connection = TornadoConnection(
                self.parameters,
                on_open_callback=self.on_connected,
                stop_ioloop_on_close=False,
                on_open_error_callback=self.on_open_error)
            self.connection.add_on_close_callback(self.on_closed)
        except:
            logging.info("connect faield")

    def on_open_error(self, unused_connection, err):
        sys.exit(1)

    def on_connected(self, connection):
        logging.info('PikaClient: connected to RabbitMQ')
        self.connection.channel(self.on_exchange_declare)

    def on_exchange_declare(self, channel):
        logging.info('PikaClient: Channel %s open, Declaring exchange' %
                     channel)
        self.channel = channel
        self.channel.exchange_declare(self.on_queue_declare,
                                      exchange='calc_fibonacci',
                                      exchange_type='direct')
        self.channel.exchange_declare(self.on_queue_declare,
                                      exchange='notification',
                                      exchange_type='direct')

    def on_queue_declare(self, method_frame):
        logging.info('PikaClient: Channel open, Declaring queue')
        self.channel.queue_declare(self.on_queue_bind,
                                   queue='calc_fibonacci')  #, durable=True)
        self.channel.queue_declare(self.on_queue_bind,
                                   queue='notification')  #, durable=True)

    def on_queue_bind(self, method_frame):
        logging.info('Queue bound')
        self.channel.queue_bind(self.on_consume_bind,
                                queue="calc_fibonacci",
                                exchange="calc_fibonacci",
                                routing_key="calc_fibonacci")
        self.channel.queue_bind(self.on_consume_bind,
                                queue="notification",
                                exchange="notification",
                                routing_key="notification")

    def on_consume_bind(self, frame):
        logging.info("Consume bind")
        self.channel.basic_qos(prefetch_count=1)
        self.channel.basic_consume(self.on_response,
                                   queue='calc_fibonacci',
                                   no_ack=False)

    def on_response(self, channel, method, properties, body):
        logging.info('on_response')
        message = pickle.loads(body)
        logging.info(message)

        uuid, index = message['uuid'], message['index']
        value = CaculateWorker.fibonacci(index)
        self.cache_cacalate(index, value)

        # self.channel.exchange_declare(exchange="notification", exchange_type="direct")
        # self.channel.queue_declare(queue='notification')
        # self.channel.queue_bind(exchange='notification', queue=notification_queue, routing_key='notification')

        result = {
            'id': uuid,
            'index': index,
            'value': value,
        }
        logging.info(result)

        channel.basic_publish(exchange='notification',
                              routing_key='notification',
                              body=pickle.dumps(result))
        logging.info("publish done")
        channel.basic_ack(delivery_tag=method.delivery_tag)

    def on_closed(self, connection):
        logging.info('PikaClient: rabbit connection closed')
        self.connection.close()
        self.channel.close()
        self.ioloop.stop()
Exemplo n.º 38
0
class MQConnection(object):
    """
    MQ连接管理类
    """
    def __init__(self, url, type='producer', callback=None, *arg, **settings):
        """Create a new instance of the MQConnection class, passing in the AMQP
        URL used to connect to RabbitMQ.

        :param str amqp_url: The AMQP url to connect with
        :param str type: connection type,for excmple,'consumer','producer'
        :param str callback: if type is 'consumer',callback is not None

        """
        self._connection = None
        self._channel = None
        self._closing = False
        self._consumer_tag = None
        self._url = url
        self._type = type
        self._was_consuming = False
        self._was_publishing = False
        self._reconnect_delay = 0
        self._callback = callback
        self.EXCHANGE = settings.get('exchange')
        self.QUEUE = settings.get('queue')
        self.ROUTING_KEY = settings.get('routing_key')
        self.EXCHANGE_TYPE = settings.get('exchange_type')
        self.AE_EXCHANGE = settings.get('ae_exchange')
        self.AE_QUEUE = settings.get('ae_queue')
        self.AE_EXCHANGE_TYPE = settings.get('ae_exchange_type')
        self.DL_EXCHANGE = settings.get('dl_exchange')
        self.DL_QUEUE = settings.get('dl_queue')
        self.DL_EXCHANGE_TYPE = settings.get('dl_exchange_type')
        self._passive = settings.get('passive', True)
        self._durable = settings.get('durable', True)
        self._prefetch_count = settings.get('prefetch_count', 128)

    @exception_catch
    def connect(self):
        """This method connects to RabbitMQ, returning the connection handle.
        When the connection is established, the on_connection_open method
        will be invoked by pika.

        :rtype: pika.SelectConnection

        """
        LOGGER.info('Connecting to %s', self._url)
        self._connection = TornadoConnection(
            pika.URLParameters(self._url),
            on_open_callback=self.on_connection_open,
            on_open_error_callback=self.on_connection_open_error)
        return self._connection

    def on_connection_open_error(self, _unused_connection, err):
        """This method is called by pika if the connection to RabbitMQ
        can't be established.
        :param pika.SelectConnection _unused_connection: The connection
        :param Exception err: The error
        """
        reconnect_delay = self._get_reconnect_delay()
        LOGGER.error('Connection open failed, reopening in %d seconds: %s',
                     reconnect_delay, err)
        self._connection.ioloop.call_later(reconnect_delay, self.reconnect)

    def close_connection(self):
        """This method closes the connection to RabbitMQ."""
        LOGGER.info('Closing connection')
        self._connection.close()

    def add_on_connection_close_callback(self):
        """This method adds an on close callback that will be invoked by pika
        when RabbitMQ closes the connection to the publisher unexpectedly.

        """
        LOGGER.info('Adding connection close callback')
        self._connection.add_on_close_callback(self.on_connection_closed)

    def on_connection_closed(self, connection, reason):
        """This method is invoked by pika when the connection to RabbitMQ is
        closed unexpectedly. Since it is unexpected, we will reconnect to
        RabbitMQ if it disconnects.

        :param pika.connection.Connection connection: The closed connection obj
        :param Exception reason: exception representing reason for loss of
            connection.

        """
        self._channel = None
        if self._closing:
            pass
            # self._connection.ioloop.stop()
        else:
            reconnect_delay = self._get_reconnect_delay()
            LOGGER.warning('Connection closed, reopening in %d seconds: %s',
                           reconnect_delay, reason)
            self._connection.ioloop.call_later(reconnect_delay, self.reconnect)

    def on_connection_open(self, unused_connection):
        """This method is called by pika once the connection to RabbitMQ has
        been established. It passes the handle to the connection object in
        case we need it, but in this case, we'll just mark it unused.

        :param pika.SelectConnection _unused_connection: The connection

        """
        LOGGER.info('Connection opened')
        self.add_on_connection_close_callback()
        self.open_channel()

    def reconnect(self):
        """Will be invoked by the IOLoop timer if the connection is
        closed. See the on_connection_closed method.

        """
        self._was_consuming = False
        self._was_publishing = False
        if not self._closing:
            # Create a new connection
            self._connection = self.connect()

    def add_on_channel_close_callback(self):
        """This method tells pika to call the on_channel_closed method if
        RabbitMQ unexpectedly closes the channel.

        """
        LOGGER.info('Adding channel close callback')
        self._channel.add_on_close_callback(self.on_channel_closed)

    def on_channel_closed(self, channel, reason):
        """Invoked by pika when RabbitMQ unexpectedly closes the channel.
        Channels are usually closed if you attempt to do something that
        violates the protocol, such as re-declare an exchange or queue with
        different parameters. In this case, we'll close the connection
        to shutdown the object.

        :param pika.channel.Channel: The closed channel
        :param Exception reason: why the channel was closed

        """
        LOGGER.warning('Channel %i was closed: %s', channel, reason)
        if self._connection.is_open:
            self._connection.close()

    def on_channel_open(self, channel):
        """This method is invoked by pika when the channel has been opened.
        The channel object is passed in so we can make use of it.

        Since the channel is now open, we'll declare the exchange to use.

        :param pika.channel.Channel channel: The channel object

        """
        LOGGER.info('Channel opened')
        self._channel = channel
        self.add_on_channel_close_callback()
        self.setup_exchange(self.EXCHANGE)
        if self.AE_EXCHANGE:
            self.setup_ae_exchange(self.AE_EXCHANGE)
        if self.DL_EXCHANGE:
            self.setup_dl_exchange(self.DL_EXCHANGE)

    @exception_catch
    def setup_exchange(self, exchange_name):
        """Setup the exchange on RabbitMQ by invoking the Exchange.Declare RPC
        command. When it is complete, the on_exchange_declareok method will
        be invoked by pika.

        :param str|unicode exchange_name: The name of the exchange to declare

        """
        cb = functools.partial(self.on_exchange_declareok,
                               userdata=exchange_name)
        args = {}
        if self.AE_EXCHANGE:
            args['alternate-exchange'] = self.AE_EXCHANGE

        self._channel.exchange_declare(passive=self._passive,
                                       durable=self._durable,
                                       exchange=exchange_name,
                                       exchange_type=self.EXCHANGE_TYPE,
                                       arguments=args,
                                       callback=cb)

    @exception_catch
    def setup_ae_exchange(self, exchange_name):
        """Setup the exchange on RabbitMQ by invoking the Exchange.Declare RPC
        command. When it is complete, the on_exchange_declareok method will
        be invoked by pika.

        :param str|unicode exchange_name: The name of the exchange to declare

        """
        ae_cb = functools.partial(self.on_ae_exchange_declareok,
                                  userdata=exchange_name)
        self._channel.exchange_declare(passive=self._passive,
                                       durable=False,
                                       exchange=exchange_name,
                                       exchange_type=self.AE_EXCHANGE_TYPE,
                                       arguments={},
                                       callback=ae_cb)

    @exception_catch
    def setup_dl_exchange(self, exchange_name):
        """Setup the exchange on RabbitMQ by invoking the Exchange.Declare RPC
        command. When it is complete, the on_exchange_declareok method will
        be invoked by pika.

        :param str|unicode exchange_name: The name of the exchange to declare

        """
        cb = functools.partial(self.on_dl_exchange_declareok,
                               userdata=exchange_name)
        self._channel.exchange_declare(passive=self._passive,
                                       durable=False,
                                       exchange=exchange_name,
                                       exchange_type=self.DL_EXCHANGE_TYPE,
                                       arguments={},
                                       callback=cb)

    def on_exchange_declareok(self, _unused_frame, userdata):
        """Invoked by pika when RabbitMQ has finished the Exchange.Declare RPC
        command.
        :param pika.Frame.Method unused_frame: Exchange.DeclareOk response frame
        :param str|unicode userdata: Extra user data (exchange name)
        """
        LOGGER.info('Exchange declared: %s', userdata)
        self.setup_queue(self.QUEUE)

    def on_ae_exchange_declareok(self, _unused_frame, userdata):
        """Invoked by pika when RabbitMQ has finished the Exchange.Declare RPC
        command.
        :param pika.Frame.Method unused_frame: Exchange.DeclareOk response frame
        :param str|unicode userdata: Extra user data (exchange name)
        """
        LOGGER.info('Exchange declared: %s', userdata)
        self.setup_ae_queue(self.AE_QUEUE)

    def on_dl_exchange_declareok(self, _unused_frame, userdata):
        """Invoked by pika when RabbitMQ has finished the Exchange.Declare RPC
        command.
        :param pika.Frame.Method unused_frame: Exchange.DeclareOk response frame
        :param str|unicode userdata: Extra user data (exchange name)
        """
        LOGGER.info('Exchange declared: %s', userdata)
        self.setup_dl_queue(self.DL_QUEUE)

    @exception_catch
    def setup_queue(self, queue_name):
        """Setup the queue on RabbitMQ by invoking the Queue.Declare RPC
        command. When it is complete, the on_queue_declareok method will
        be invoked by pika.
        :param str|unicode queue_name: The name of the queue to declare.
        """
        LOGGER.info('Declaring queue %s', queue_name)
        if self._type == 'consumer' and self.EXCHANGE_TYPE == 'x-modulus-hash':
            if not self._was_consuming:
                self.start_consuming()
        else:
            args = {}
            if self.DL_EXCHANGE:
                args['x-dead-letter-exchange'] = self.DL_EXCHANGE

            self._channel.queue_declare(durable=self._durable,
                                        passive=self._passive,
                                        queue=queue_name,
                                        arguments=args,
                                        callback=self.on_queue_declareok)

    @exception_catch
    def setup_ae_queue(self, queue_name):
        """Setup the queue on RabbitMQ by invoking the Queue.Declare RPC
        command. When it is complete, the on_queue_declareok method will
        be invoked by pika.
        :param str|unicode queue_name: The name of the queue to declare.
        """
        LOGGER.info('Declaring queue %s', queue_name)
        self._channel.queue_declare(durable=False,
                                    passive=self._passive,
                                    queue=queue_name,
                                    callback=self.on_ae_queue_declareok)

    @exception_catch
    def setup_dl_queue(self, queue_name):
        """Setup the queue on RabbitMQ by invoking the Queue.Declare RPC
        command. When it is complete, the on_queue_declareok method will
        be invoked by pika.
        :param str|unicode queue_name: The name of the queue to declare.
        """
        LOGGER.info('Declaring queue %s', queue_name)
        self._channel.queue_declare(durable=False,
                                    passive=self._passive,
                                    queue=queue_name,
                                    callback=self.on_dl_queue_declareok)

    @exception_catch
    def on_queue_declareok(self, _unused_frame):
        """Method invoked by pika when the Queue.Declare RPC call made in
        setup_queue has completed. In this method we will bind the queue
        and exchange together with the routing key by issuing the Queue.Bind
        RPC command. When this command is complete, the on_bindok method will
        be invoked by pika.
        :param pika.frame.Method method_frame: The Queue.DeclareOk frame
        """
        LOGGER.info('Binding %s to %s with %s', self.EXCHANGE, self.QUEUE,
                    self.ROUTING_KEY)
        self._channel.queue_bind(self.QUEUE,
                                 self.EXCHANGE,
                                 routing_key=self.ROUTING_KEY,
                                 callback=self.on_bindok)

    @exception_catch
    def on_ae_queue_declareok(self, _unused_frame):
        """Method invoked by pika when the Queue.Declare RPC call made in
        setup_queue has completed. In this method we will bind the queue
        and exchange together with the routing key by issuing the Queue.Bind
        RPC command. When this command is complete, the on_bindok method will
        be invoked by pika.
        :param pika.frame.Method method_frame: The Queue.DeclareOk frame
        """
        LOGGER.info('Binding %s to %s with %s', self.AE_EXCHANGE,
                    self.AE_QUEUE, self.ROUTING_KEY)
        self._channel.queue_bind(self.AE_QUEUE,
                                 self.AE_EXCHANGE,
                                 routing_key=self.ROUTING_KEY,
                                 callback=self.on_bindok)

    @exception_catch
    def on_dl_queue_declareok(self, _unused_frame):
        """Method invoked by pika when the Queue.Declare RPC call made in
        setup_queue has completed. In this method we will bind the queue
        and exchange together with the routing key by issuing the Queue.Bind
        RPC command. When this command is complete, the on_bindok method will
        be invoked by pika.
        :param pika.frame.Method method_frame: The Queue.DeclareOk frame
        """
        LOGGER.info('Binding %s to %s with %s', self.DL_EXCHANGE,
                    self.DL_QUEUE, self.ROUTING_KEY)
        self._channel.queue_bind(self.DL_QUEUE,
                                 self.DL_EXCHANGE,
                                 routing_key=self.ROUTING_KEY,
                                 callback=self.on_bindok)

    def on_bindok(self, unused_frame):
        """Invoked by pika when the Queue.Bind method has completed. At this
        point we will start consuming messages by calling start_consuming
        which will invoke the needed RPC commands to start the process.

        :param pika.frame.Method unused_frame: The Queue.BindOk response frame

        """
        LOGGER.info('Queue bound')
        if self._type == 'consumer':
            if not self._was_consuming:
                self.start_consuming()
        else:
            if not self._was_publishing:
                self.start_publishing()

    @exception_catch
    def stop_consuming(self):
        """Tell RabbitMQ that you would like to stop consuming by sending the
        Basic.Cancel RPC command.

        """
        if self._channel:
            LOGGER.info('Sending a Basic.Cancel RPC command to RabbitMQ')
            self._channel.basic_cancel(self.on_cancelok, self._consumer_tag)

    @exception_catch
    def start_consuming(self):
        """This method sets up the consumer by first calling
        add_on_cancel_callback so that the object is notified if RabbitMQ
        cancels the consumer. It then issues the Basic.Consume RPC command
        which returns the consumer tag that is used to uniquely identify the
        consumer with RabbitMQ. We keep the value to use it when we want to
        cancel consuming. The on_message method is passed in as a callback pika
        will invoke when a message is fully received.

        """
        LOGGER.info('start consuming')
        self._was_consuming = True
        self.add_on_cancel_callback()
        self._channel.basic_qos(prefetch_count=self._prefetch_count)
        self._consumer_tag = self._channel.basic_consume(
            self.QUEUE, self._callback)

    def add_on_cancel_callback(self):
        """Add a callback that will be invoked if RabbitMQ cancels the consumer
        for some reason. If RabbitMQ does cancel the consumer,
        on_consumer_cancelled will be invoked by pika.
        """
        LOGGER.info('Adding consumer cancellation callback')
        self._channel.add_on_cancel_callback(self.on_consumer_cancelled)

    def on_consumer_cancelled(self, method_frame):
        """Invoked by pika when RabbitMQ sends a Basic.Cancel for a consumer
        receiving messages.
        :param pika.frame.Method method_frame: The Basic.Cancel frame
        """
        LOGGER.info('Consumer was cancelled remotely, shutting down: %r',
                    method_frame)
        if self._channel:
            self._channel.close()

    def start_publishing(self):
        """This method will enable delivery confirmations and schedule the
        first message to be sent to RabbitMQ
        """
        LOGGER.info('start publishing')
        self._was_publishing = True
        self.enable_delivery_confirmations()
        # self.schedule_next_message()

    def enable_delivery_confirmations(self):
        """Send the Confirm.Select RPC method to RabbitMQ to enable delivery
        confirmations on the channel. The only way to turn this off is to close
        the channel and create a new one.
        When the message is confirmed from RabbitMQ, the
        on_delivery_confirmation method will be invoked passing in a Basic.Ack
        or Basic.Nack method from RabbitMQ that will indicate which messages it
        is confirming or rejecting.
        """
        LOGGER.info('Issuing Confirm.Select RPC command')
        self._channel.confirm_delivery(self._callback)

    def close_channel(self):
        """Call to close the channel with RabbitMQ cleanly by issuing the
        Channel.Close RPC command.

        """
        LOGGER.info('Closing the channel')
        self._channel.close()

    @exception_catch
    def open_channel(self):
        """Open a new channel with RabbitMQ by issuing the Channel.Open RPC
        command. When RabbitMQ responds that the channel is open, the
        on_channel_open callback will be invoked by pika.

        """
        LOGGER.info('Creating a new channel')
        self._connection.channel(on_open_callback=self.on_channel_open)

    def get_channel(self):
        """return _channel.
        """
        return self._channel

    def get_connection(self):
        """return _connection.
        """
        return self._connection

    def stop(self):
        """Cleanly shutdown the connection to RabbitMQ by stopping the consumer
        with RabbitMQ. When RabbitMQ confirms the cancellation, on_cancelok
        will be invoked by pika, which will then closing the channel and
        connection. The IOLoop is started again because this method is invoked
        when CTRL-C is pressed raising a KeyboardInterrupt exception. This
        exception stops the IOLoop which needs to be running for pika to
        communicate with RabbitMQ. All of the commands issued prior to starting
        the IOLoop will be buffered but not processed.

        """
        self._closing = True
        LOGGER.info('Stopped')

    def _get_reconnect_delay(self):
        if self._was_consuming:
            self._reconnect_delay = 0
        else:
            self._reconnect_delay += 1
        if self._reconnect_delay > 30:
            self._reconnect_delay = 30
        return self._reconnect_delay
Exemplo n.º 39
0
class PikaClient(object):

    def __init__(self):
        # Construct a queue name we'll use for this instance only
        self.queue_name = "hello"

        # Default values
        self.connected = False
        self.connecting = False
        self.connection = None
        self.channel = None

        # A place for us to keep messages sent to us by Rabbitmq
        self.messages = list()

        # A place for us to put pending messages while we're waiting to connect
        self.pending = list()

    def connect(self):
        if self.connecting:
            pika.log.info('PikaClient: Already connecting to RabbitMQ')
            return
        pika.log.info('PikaClient: Connecting to RabbitMQ on localhost:5672')
        self.connecting = True

        param = pika.ConnectionParameters(host='115.146.93.175')
        self.connection = TornadoConnection(param,
                                            on_open_callback=self.on_connected)
        self.connection.add_on_close_callback(self.on_closed)

    def on_connected(self, connection):
        pika.log.info('PikaClient: Connected to RabbitMQ on localhost:5672')
        self.connected = True
        self.connection = connection
        self.connection.channel(self.on_channel_open)

    def on_channel_open(self, channel):
        pika.log.info('PikaClient: Channel Open, Declaring Exchange')
        self.channel = channel
        self.channel.exchange_declare(exchange='',
                                      #type="direct",
                                      #auto_delete=True,
                                      #durable=False,
                                      callback=self.on_exchange_declared)

    def on_exchange_declared(self, frame):
        pika.log.info('PikaClient: Exchange Declared, Declaring Queue')
        self.channel.queue_declare(queue=self.queue_name,
                                   #auto_delete=True,
                                   #durable=False,
                                   #exclusive=False,
                                   callback=self.on_queue_declared)

    def on_queue_declared(self, frame):
        pika.log.info('PikaClient: Queue Declared, Binding Queue')
        self.channel.queue_bind(exchange='',
                                queue=self.queue_name,
                                routing_key='hello',
                                callback=self.on_queue_bound)

    def on_queue_bound(self, frame):
        pika.log.info('PikaClient: Queue Bound, Issuing Basic Consume')
        self.channel.basic_consume(consumer_callback=self.on_pika_message,
                                   queue=self.queue_name,
                                   no_ack=True)
        # Send any messages pending
        for properties, body in self.pending:
            self.channel.basic_publish(exchange='',
                                       routing_key='hello',
                                       body=body,
                                       properties=properties)

    def on_pika_message(self, channel, method, header, body):
        pika.log.info('PikaCient: Message receive, delivery tag #%i' % \
                     method.delivery_tag)
        # Append it to our messages list
        self.messages.append(body)

    def on_basic_cancel(self, frame):
        pika.log.info('PikaClient: Basic Cancel Ok')
        # If we don't have any more consumer processes running close
        self.connection.close()

    def on_closed(self, connection):
        # We've closed our pika connection so stop the demo
        tornado.ioloop.IOLoop.instance().stop()

    def sample_message(self, tornado_request):
        # Build a message to publish to RabbitMQ
        body = '%.8f: Request from %s [%s]' % \
               (tornado_request._start_time,
                tornado_request.remote_ip,
                tornado_request.headers.get("User-Agent"))

        # Send the message
        properties = pika.BasicProperties(content_type="text/plain",
                                          delivery_mode=1)
        self.channel.basic_publish(exchange='',
                                   routing_key='hello',
                                   body=body,
                                   properties=properties)

    def get_messages(self):
        # Get the messages to return, then empty the list
        output = self.messages
        self.messages = list()
        return output
Exemplo n.º 40
0
class PikaClient(object):
    '''
    Helper class to manage RabbitMQ/Pika interface
    '''
    def __init__(self):
        # Construct queue names request and response
        self.queue_name_req = 'request'
        self.queue_name_resp = 'response'

        # A place to keep requests and reponses from Rabbitmq
        self.req_listeners = set([])
        self.resp_listeners = set([])

    def connect(self):
        pika.log.info('PikaClient: Connecting to RabbitMQ on localhost:5672')

        credentials = pika.PlainCredentials('guest', 'guest')
        param = pika.ConnectionParameters(host='localhost',
                                          port=5672,
                                          virtual_host="/",
                                          credentials=credentials)
        self.connection = TornadoConnection(param,
                                            on_open_callback=self.on_connected)
        self.connection.add_on_close_callback(self.on_closed)

    def on_connected(self, connection):
        pika.log.info('PikaClient: Connected to RabbitMQ on localhost:5672')
        self.connection = connection
        self.connection.channel(self.on_channel_open)

    def on_channel_open(self, channel):
        pika.log.info('PikaClient: Channel Open, Declaring Exchange')
        self.channel = channel
        self.channel.exchange_declare(exchange='tornado',
                                      type="topic",
                                      auto_delete=True,
                                      durable=False,
                                      callback=self.on_exchange_declared)

    def on_exchange_declared(self, frame):
        pika.log.info('PikaClient: Exchange Declared, Declaring Queues')
        self.channel.queue_declare(queue=self.queue_name_req,
                                   auto_delete=True,
                                   durable=False,
                                   exclusive=False)

        self.channel.queue_declare(queue=self.queue_name_resp,
                                   auto_delete=True,
                                   durable=False,
                                   exclusive=False,
                                   callback=self.on_queue_declared)

    def on_queue_declared(self, frame):
        pika.log.info('PikaClient: Queues Declared, Binding Queues')
        self.channel.queue_bind(exchange='tornado',
                                queue=self.queue_name_req,
                                routing_key='*.longpoll.request')

        self.channel.queue_bind(exchange='tornado',
                                queue=self.queue_name_resp,
                                routing_key='*.longpoll.response',
                                callback=self.on_queue_bound)

    def on_queue_bound(self, frame):
        pika.log.info('PikaClient: Queue Bound, Issuing Basic Consume')
        self.channel.basic_consume(consumer_callback=self.on_pika_req_message,
                                   queue=self.queue_name_req,
                                   no_ack=True)

        self.channel.basic_consume(consumer_callback=self.on_pika_resp_message,
                                   queue=self.queue_name_resp,
                                   no_ack=True)

    def on_pika_req_message(self, channel, method, header, body):
        log = 'PikaCient: Request Message received: %s'
        pika.log.info(log % body)
        self.notify_listeners(body, 'request')

    def on_pika_resp_message(self, channel, method, header, body):
        log = 'PikaCient: Response Message received: %s'
        pika.log.info(log % body)
        self.notify_listeners(body, 'response')

    def on_basic_cancel(self, frame):
        pika.log.info('PikaClient: Basic Cancel Ok')
        # If we don't have any more consumer processes running close
        self.connection.close()

    def on_closed(self, connection):
        # We've closed our pika connection so stop the demo
        tornado.ioloop.IOLoop.instance().stop()

    def server_test(self, tornado_request, action):
        # Prepare POST information for RabbitMQ
        if action == 'request':
            body = json.dumps(tornado_request.arguments)
        elif action == 'response':
            body = tornado_request.body

        # Send the message
        properties = pika.BasicProperties(
            content_type="application/json",
            delivery_mode=1
            )

        self.channel.basic_publish(exchange='tornado',
                                   routing_key='*.longpoll.' + action,
                                   properties=properties,
                                   body=body)

    def notify_listeners(self, message, action):
        # Deliver the message from RabbitMQ and finish the connection
        if action == 'request':
            listeners = self.req_listeners.copy()
        elif action == 'response':
            listeners = self.resp_listeners.copy()

        for listener in listeners:
            listener.finish(json.dumps(message))
            pika.log.info('PikaClient: notified %s' % repr(listener))
            self.remove_listener(listener, action)

    def add_listener(self, listener, action):
        if action == 'request':
            self.req_listeners.add(listener)
        elif action == 'response':
            self.resp_listeners.add(listener)
        pika.log.info('PikaClient: listener %s added' % repr(listener))

    def remove_listener(self, listener, action):
        try:
            if action == 'request':
                self.req_listeners.remove(listener)
            elif action == 'response':
                self.resp_listeners.remove(listener)
            pika.log.info('PikaClient: listener %s removed' % repr(listener))
        except KeyError:
            pass