在 Tweepy 和 Tornado WebSocket 中的类之间传递数据 [英] Passing data between classes in Tweepy and Tornado WebSocket

查看:28
本文介绍了在 Tweepy 和 Tornado WebSocket 中的类之间传递数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个主要模块,Tornado WebSocket 和 Tweepy Streaming,我试图让它们相互通信.

I have two main modules, Tornado WebSocket and Tweepy Streaming, and I'm trying to get them to talk to each other.

StdOutListener Tweepy 类中的on_status 下面(用<-- 标记),我想调用WSHandler.on_message Tornado 类更高,从 on_status 传递数据.

Under on_status in the StdOutListener Tweepy class below (marked with <--), I'd like to call the WSHandler.on_message Tornado class higher up, with data passed from on_status.

但是,我无法这样做,因为我收到与未定义实例等相关的错误消息,使用以下代码.非常感谢任何帮助!

I'm not able to do so however, as I get error-messages related to undefined instances etc. with the code below. Any help greatly appreciated!

(此外,我设法同时运行两个模块的唯一非阻塞方式是使用线程,因为 IOLoop.add_callback 不保留 StdOutListener 阻止.我很想知道为什么或是否推荐使用此实现.谢谢!)

(Also, the only non-blocking way I've managed to run both modules at the same time is with threading, as the IOLoop.add_callback does not keep StdOutListener from blocking. I'd love to know why or if this implementation is recommended. Thanks!)

import os.path
import tornado.httpserver
import tornado.websocket
import tornado.ioloop
import tornado.web
import threading
import time
import datetime

# websocket
class FaviconHandler(tornado.web.RequestHandler):
    def get(self):
        self.redirect('/static/favicon.ico')

class WebHandler(tornado.web.RequestHandler):
    def get(self):
        self.render("websockets.html")

class WSHandler(tornado.websocket.WebSocketHandler):
    def open(self): 
        cb = tornado.ioloop.PeriodicCallback(self.spew, 1000, io_loop=main_loop)
        cb.start()
        print 'new connection'
        self.write_message("Hi, client: connection is made ...")

    def on_message(self, message):
        print 'message received: \"%s\"' % message
        self.write_message("Echo: \"" + message + "\"")
        if (message == "green"):
            self.write_message("green!")

    def on_close(self):
        print 'connection closed'

    def spew(self):
        msg = 'spew!'
        print(msg)
        self.on_message(msg)

handlers = [
    (r"/favicon.ico", FaviconHandler),
    (r'/static/(.*)', tornado.web.StaticFileHandler, {'path': 'static'}),
    (r'/', WebHandler),
    (r'/ws', WSHandler),
]

settings = dict(
    template_path=os.path.join(os.path.dirname(__file__), "static"),
)

application = tornado.web.Application(handlers, **settings)


# tweepy
from tweepy.streaming import StreamListener
from tweepy import OAuthHandler
from tweepy import Stream
import simplejson as json


# new stream listener 
class StdOutListener(StreamListener, WSHandler):
    """ A listener handles tweets are the received from the stream. 
    This is a basic listener that just prints received tweets to stdout.

    """

    # tweet handling
    def on_status(self, status):
        print('@%s: %s' % (status.user.screen_name, status.text))
        WSHandler.on_message(status.text) # <--- THIS is where i want to send a msg to WSHandler.on_message

    # limit handling
    def on_limit(self, track):
        return

    # error handling
    def on_error(self, status):
        print status


def OpenStream():
    consumer_key="[redacted]"
    consumer_secret="[redacted]"
    access_token="[redacted]"
    access_token_secret="[redacted]"
    keyword = 'whatever'

    l = StdOutListener()
    auth = OAuthHandler(consumer_key, consumer_secret)
    auth.set_access_token(access_token, access_token_secret)
    stream = Stream(auth, l, gzip=True) 
    stream.filter(track=[keyword])



if __name__ == "__main__":
    threading.Thread(target=OpenStream).start()
    http_server = tornado.httpserver.HTTPServer(application)
    http_server.listen(8888)
    main_loop = tornado.ioloop.IOLoop.instance()
#   main_loop.add_callback(OpenStream)
    main_loop.start()

推荐答案

on_message 是一个实例方法,而不是一个类方法.您需要在实例上调用它,如下所示:

on_message is an instance method, not a class method. You need to call it on an instance, like this:

handler = WSHandler()
handler.on_message('hello world')

但是,您不能仅仅这样做,因为需要通过浏览器连接创建实例才能实际发送和接收消息.

However, you can't just do that as instances need to be created by a browser connection in order to actually send and receive messages.

您可能想要的是保留一个打开连接列表( Tornado websocket 演示就是一个很好的例子):

What you probably want is to keep a list of open connections (the Tornado websocket demo is a good example of this):

class WSHandler(tornado.websocket.WebSocketHandler):
    connections = []

    def open(self):
        self.connections.append(self)

    ....

    def on_close(self):
        self.connections.remove(self)

然后,在 StdOutListener.on_status 中,您可以执行以下操作:

then, in StdOutListener.on_status, you can do something like:

for connection in WSHandler.connections:
    connection.write_message(status.text)

这篇关于在 Tweepy 和 Tornado WebSocket 中的类之间传递数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆