python - Django/gevent socket.IO 与 redis pubsub。我把东西放在哪里?

标签 python django socket.io publish-subscribe gevent

我有一个独立的 python 脚本,它简单地从 Twitter 的流 API 捕获数据,然后在收到每条消息时,使用它发布到 channel “tweets”的 redis pubsub。这是该脚本:

def main():
    username = "username"
    password = "password"
    track_list = ["apple", "microsoft", "google"]

    with tweetstream.FilterStream(username, password, track=track_list) as stream:
        for tweet in stream:
            text = tweet["text"]
            user = tweet["user"]["screen_name"]
            message = {"text": text, "user": user}
            db.publish("tweets", message)

if __name__ == '__main__':
    try:
        print "Started..."
        main()
    except KeyboardInterrupt:
        print '\nGoodbye!'

我的服务器端 socket.io 实现是使用 django-socketio(基于 gevent-socketio)完成的 https://github.com/stephenmcd/django-socketio它只是提供了一些辅助装饰器和一个 broadcast_channel 方法。因为它是在 django 中完成的,所以我只是将这段代码简单地放在 views.py 中,以便它们被导入。我的 views.py 代码:

def index(request):
    return render_to_response("twitter_app/index.html", {
    }, context_instance=RequestContext(request))

def _listen(socket):
    db = redis.Redis(host="localhost", port=6379, db=0)
    client = db.pubsub()
    client.subscribe("tweets")
    tweets = client.listen()

    while True:
        tweet = tweets.next()
        tweet_data = ast.literal_eval(tweet["data"])
        message = {"text": tweet_data["text"], "user": tweet_data["user"], "type": "tweet"}
        socket.broadcast_channel(message)

@on_subscribe(channel="livestream")
def subscribe(request, socket, context, channel):
    g = Greenlet.spawn(_listen, socket)

客户端 socket.io JavaScript 简单地连接并订阅 channel “livestream”,并捕获任何接收到该 channel 的消息:

var socket = new io.Socket();
socket.connect();
socket.on('connect', function() {
    socket.subscribe("livestream");
});
socket.on('message', function(data) {
    console.log(data);
});

此代码的明显问题是,每次新用户或浏览器窗口打开页面时,都会生成一个新的 _listen 方法,推文会为每个用户订阅和广播,从而导致在客户。我的问题是,将 _listen 方法放在哪里比较合适,这样无论客户端数量多少,它都只创建一次?另外,请记住 broadcast_channel 方法是套接字实例的方法。

最佳答案

问题是我在应该使用 socket.send 的时候使用了 socket.broadcast_channel。

关于python - Django/gevent socket.IO 与 redis pubsub。我把东西放在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7678402/

相关文章:

python - 捕获我在计算中得到 NaN 的那一刻

python - Django 无法呈现注销模板

python - Django 分页中的 EmptyPage 错误

javascript - 客户端 Socket.io 持续断开并重新连接到 websocket

javascript - 无法让 socket.io-emitter 与 socket.io-redis 一起工作

javascript - 我可以在 socket.io "socket.on(eventName, callback)"中使用返回 promise 吗?

python - BeautifulSoup:无法获取下一个元素

python - Pandas 。如何从 ZIP 存档中读取 Excel 文件

python - 为什么 Python 输出相同值的字符串和 unicode 不同?

python - 从 Django-Oscar 扩展客户的 View