2012-09-18 19 views
2

我有两个主要模块,Tornado WebSocket和Tweepy Streaming,我试图让他们相互交谈。在Tweepy和Tornado中的类之间传递数据WebSocket

在下面的StdOutListener Tweepy类(标有<--on_status,我想打电话给WSHandler.on_message旋风类上涨,从on_status传递的数据。

但是我无法做到这一点,因为我用下面的代码得到了与未定义实例等相关的错误消息。任何帮助非常感谢! (另外,我同时运行两个模块的唯一非阻塞方式是使用线程,因为IOLoop.add_callback不会阻止StdOutListener阻止。我很想知道为什么或者如果这个实现谢谢!)

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() 

回答

4

on_message是一个实例方法,而不是一个类方法。你需要调用它的一个实例,像这样:

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

但是,你不能仅仅做到这一点的情况下,需要由以实际发送和接收消息的浏览器连接创建。

你可能想要的是保持开放的连接(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,你可以这样做:

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

点上。谢谢 – knutole

+0

哇,那很快! –