我正在使用Redis以及我的Tornado应用程序与asyc客户端Brukva,当我查看Brukva站点上的示例应用程序时,他们正在websocket中的“ init ”方法上建立新连接

class MessagesCatcher(tornado.websocket.WebSocketHandler):
    def __init__(self, *args, **kwargs):
        super(MessagesCatcher, self).__init__(*args, **kwargs)
        self.client = brukva.Client()
        self.client.connect()
        self.client.subscribe('test_channel')

    def open(self):
        self.client.listen(self.on_message)

    def on_message(self, result):
        self.write_message(str(result.body))

    def close(self):
        self.client.unsubscribe('test_channel')
        self.client.disconnect()

在websocket的情况下很好但是如何在常见的Tornado RequestHandler post方法中处理它说长轮询操作(发布 - 订阅模型) 我在更新处理程序的每个post方法中创建新的客户端连接这是正确的方法吗? 当我在redis控制台上检查时,我看到每个新的post操作都会增加客户端。

在此输入图像描述

这是我的代码示例。

c = brukva.Client(host = '127.0.0.1')
c.connect()

class MessageNewHandler(BaseHandler):
    @tornado.web.authenticated
    def post(self):

        self.listing_id = self.get_argument("listing_id")
        message = {
            "id": str(uuid.uuid4()),
            "from": str(self.get_secure_cookie("username")),
            "body": str(self.get_argument("body")),
        }
        message["html"] = self.render_string("message.html", message=message)

        if self.get_argument("next", None):
            self.redirect(self.get_argument("next"))
        else:
            c.publish(self.listing_id, message)
            logging.info("Writing message : " + json.dumps(message))
            self.write(json.dumps(message))

    class MessageUpdatesHandler(BaseHandler):
        @tornado.web.authenticated
        @tornado.web.asynchronous
        def post(self):
            self.listing_id = self.get_argument("listing_id", None)
            self.client = brukva.Client()
            self.client.connect()
            self.client.subscribe(self.listing_id)
            self.client.listen(self.on_new_messages)

        def on_new_messages(self, messages):
            # Closed client connection
            if self.request.connection.stream.closed():
                return
            logging.info("Getting update : " + json.dumps(messages.body))
            self.finish(json.dumps(messages.body))
            self.client.unsubscribe(self.listing_id)


        def on_connection_close(self):
            # unsubscribe user from channel
            self.client.unsubscribe(self.listing_id)
            self.client.disconnect()

如果您提供类似案例的示例代码,我将不胜感激。

===============>>#1 票数:11

有点晚了,但我一直在使用龙卷风 它适用于龙卷风的ioloop和tornado.gen模块

安装tornadoredis

它可以从pip安装

pip install tornadoredis

或者使用setuptools

easy_install tornadoredis

但你真的不应该这样做。 您还可以克隆存储库并将其解压缩。 然后跑

python setup.py build
python setup.py install

连接到redis

以下代码包含在main.py或同等代码中

redis_conn = tornadoredis.Client('hostname', 'port')
redis_conn.connect()

redis.connect只调用一次。 这是一个阻塞调用,所以应该在启动主ioloop之前调用它。 所有处理程序之间共享相同的连接对象。

您可以将其添加到您的应用程序设置中

settings = {
    redis = redis_conn
}
app = tornado.web.Application([('/.*', Handler),],
                              **settings)

使用tornadoredis

该连接可以作为self.settings['redis']在处理程序中使用,也可以作为BaseHandler类的属性添加。 您的请求处理程序将该类子类化并访问该属性。

class BaseHandler(tornado.web.RequestHandler):

    @property
    def redis():
        return self.settings['redis']

要与redis通信,请使用tornado.web.asynchronoustornado.gen.engine装饰器

class SomeHandler(BaseHandler):

    @tornado.web.asynchronous
    @tornado.gen.engine
    def get(self):
        foo = yield gen.Task(self.redis.get, 'foo')
        self.render('sometemplate.html', {'foo': foo}

额外的信息

可以在github repo上找到更多示例和其他功能,如连接池和管道。

===============>>#2 票数:2

你应该在你的应用程序中汇集连接。 因为看起来brukva不会自动支持这个(redis-py支持这个,但是本质上是阻塞因此龙卷风不顺利),你需要编写自己的连接池。

但是,模式非常简单。 沿着这些方向的东西(这不是真正的操作代码):

class BrukvaPool():

    __conns = {}


    def get(host, port,db):
        ''' Get a client for host, port, db '''

        key = "%s:%s:%s" % (host, port, db)

        conns = self.__conns.get(key, [])
        if conns:
            ret = conns.pop()
            return ret
        else:
           ## Init brukva client here and connect it

    def release(client):
        ''' release a client at the end of a request '''
        key = "%s:%s:%s" % (client.connection.host, client.connection.port, client.connection.db)
        self.__conns.setdefault(key, []).append(client)

它可能有点棘手,但这是主要的想法。

  ask by Burak Dede translate from so

未解决问题?本站智能推荐:

1回复

使用Redis发布/订阅连接Tornado进程

我有两个龙卷风过程X和Y X处理程序处理后请求,当此类请求到达时,除了在X进行更改外,我还想更改存储在Y一些变量。 我想使用Redis的PUB / SUB来做到这一点。 显然,在X的处理程序中,我需要将消息发布到由'Y'订阅的通道。 Y此预订应长期运行,以便每当一条消息发布到通道
4回复

类似MQTT的发布 - 使用Python和WebSockets订阅?

我正在开发一个项目,需要一个框架来处理网页和Python之间的pub / sub连接。 我已经使用了mosquitto(MQTT的开源实现)并且它可以工作,但是服务器需要一个修改的Apache模块来将WebSocket连接重定向到代理。 现在,我正在看龙卷风,但它不符合我的要求。
2回复

在收到通知后从服务器向客户端发送消息(Tornado + websockets)

我最近开始学习Websocket,并且我决定尝试学习和使用Python的framweork Tornado创建我的简单测试项目(没什么特别的,只是基本项目可以帮助我学习有关Tornado和Websockets的一般知识)。 因此,这是我的想法(工作流程): 1)我收到来自其他应用的h
1回复

带Python后端和Socket.io的Redis发布/订阅

我有一个PHP代码,它将数据发布到名为“ MESSAGE_FROM_MARS”的通道。 摘录如下: 有一个服务器端python侦听器,用于接收发布的数据,该代码段如下所示: python代码进行处理并将结果发布回去。 摘录如下: 我正在尝试使用socket.io we
4回复

如何异步使用Tornado和Redis?

我试图找到如何异步使用Redis和Tornado。 我找到了tornado-redis,但我需要的不仅仅是在代码中添加一个yield 。 我有以下代码: 我需要访问/ url并获取“Hello World”,而/wait有一个待处理的请求。 我该怎么做?
2回复

处理在python,龙卷风和redis上运行的网站中的外来字符

我已经阅读了许多相关问题,但对于如何处理这种情况并不确定。 基本问题:在网站中处理“外国”(希伯来语,希腊语,亚拉姆语等)字符的最佳方法是什么? 我知道我需要使用UTF-8编码,但是它背后的机制对我来说却迷失了。 我正在使用龙卷风作为框架,并将数据存储在Redis中。 我
1回复

使用Python订阅模式Redis

我正在尝试开发基于Python和Redis的通知系统。 我一直在检查python redis 模块,并且看到一个小的模式订阅示例: 从理论上讲,就是这样,所以我尝试了类似的方法 我正在尝试订阅每个键,以使示例最简单。 但是,我只是一开始才得到此消息,并且在更改键的值时,我什么
1回复

使用redis-py更改PubSub订阅

我有一个实时webapp,客户端从多个Redis PubSub频道接收更新,使用gevent-socketio和redis-py构建。 我正在看django-tictactoe示例中的views.py,l.26 。 当客户端发送频道的订阅消息时,它会生成一个新的greenlet。 然后
1回复

django虚拟环境安装brukva,在Tornado IO循环中工作的异步Redis客户端

我在我的一个项目中使用龙卷风和redis。 我想安装brukva与龙卷风一起工作redis。 但没有找到任何特定的指南在ubuntu中安装burkva .. 我试过pip install brukva但它没有安装包.. 谁能帮助我如何安装brukva?
1回复

如何使用pympler跟踪/修复tornado-redis中的内存泄漏?

我一直在尝试使用龙卷风Redis的 (这基本上是一个叉brükva略作修改与tornado.gen接口而不是adisp工作),以便通过使用提供事件的Redis'发布订阅 。 所以我写了一个小脚本来测试这个例子的灵感。 import os from tornado import iolo