Search code examples
python-2.7rabbitmqtornadoproducer-consumerpika

Tornado on pika consumer can't run


I want to build monitoring system using RabbitMQ and Tornado. I can run the producer and my consumer can consume the data on queue but the data cant be show on website.

This just my experiment before I using the sensor

import pika
import tornado.ioloop
import tornado.web
import tornado.websocket
import logging
from threading import Thread

logging.basicConfig(lvl=logging.INFO)
clients=[]

credentials = pika.credentials.PlainCredentials('ayub','ayub')
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.43.101',
                                5672,
                                '/',
                                credentials))
channel = connection.channel()

def threaded_rmq():
    channel.basic_consume('Queue',
                            on_message_callback= consumer_callback,
                            auto_ack=True,
                            exclusive=False,
                            consumer_tag=None,
                            arguments=None)

    channel.start_consuming()

def disconect_rmq():
    channel.stop_consuming()
    Connection.close()
    logging.info('Disconnected from broker')

def consumer_callback(ch,method,properties,body):
    for itm in clients:
        itm.write_message(body)
class SocketHandler(tornado.websocket.WebSocketHandler):
    def open(self):
        logging.info('websocket open')
        clients.remove(self)

    def close(self):
        logging.info('websocket closed')
        clients.remove(self)

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.render("websocket.html")

application = tornado.web.Application([
    (r'/ws',SocketHandler),
    (r"/", MainHandler),
])

def startTornado():
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

def stopTornado():
    tornado.ioloop.IOLoop.instance().stop()

if __name__ == "__main__":
    logging.info('starting thread RMQ')

    threadRMQ = Thread(target=threaded_rmq)
    threadRMQ.start()
    logging.info('starting thread tornado')

    threadTornado = Thread(target=startTornado)
    threadTornado.start()

    try:
        raw_input("server ready")
    except SyntaxError:
        pass
    try:
        logging.info('disconnected')
        disconnect_rmq()
    except Exception, e:
        pass
    stopTornado()

but I got this error

WARNING:tornado.access:404 GET /favicon.ico (192.168.43.10) 0.98ms

please help me


Solution

  • In your SocketHandler.open function you need to add the client not remove it.
    Also consider using a set for clients instead of a list because the remove operation will be faster:

    clients = set()
    ...
    class SocketHandler(tornado.websocket.WebSocketHandler):
        def open(self):
            logging.info('websocket open')
            clients.add(self)
    
        def close(self):
            logging.info('websocket closed')
            clients.remove(self)
    

    The message you get regarding favicon.ico is actually a warning and it's harmless (the browser is requesting an icon to show for web application but won't complain if none is available).

    You might also run into threading issues because Tornado and Pika are running in different threads so you will have to synchronize them; you can use Tornado's IOLoop.add_callback method for that.