从Requesthandler调用Tornado WebSocketHandler

1 投票
1 回答
1046 浏览
提问于 2025-04-18 15:12

我正在使用Tornado Web服务器,想要在一个请求处理器(RequestHandler)中内部调用一个WebSocket处理器(WebSocketHandler)。

我不能使用重定向功能,因为要调用的WebSocketHandler类(下面例子中的"IndexHandlerDynamic1")是通过一个类工厂(classFactory)创建的。

根据请求处理器的定义(查看这里),我的例子看起来是这样的:

class IndexHandlerDynamic1(tornado.web.WebSocketHandler):
    def initialize(self):
        print "Forwarded to Websocket"
    def open(self):
        print "WebSocket opened"
class IndexHandlerDistributor(tornado.web.RequestHandler):
    def get(self, channelId):
        IndexHandlerDynamic1(self.application, self.request)

当我请求相关的URL时,它会跳转到IndexHandlerDistributor,并调用IndexHandlerDynamic1.initialize()。

但是在客户端,浏览器控制台输出了以下错误:

Error during WebSocket handshake: Unexpected response code: 200 

显然,socket连接没有正确打开,我的错误在哪里呢?

编辑:

感谢Ben的帮助!

可惜我仍然在将用户路由到一个动态创建的类(名字和URL参数相同)时遇到问题。我希望你能通过查看我的例子理解我的问题:

app = tornado.web.Application( 
        [(r"/", IndexHandler)] + 
        [(r"/channel/(?P<channelId>[^\/]+)?", ClassFactory(channelId))] 
        ) 

如何将channelId作为参数传递给我的类工厂调用,作为请求处理器?

或者有没有其他方法可以在应用程序运行时动态改变路由?如果有的话,我可以用这种方法来解决我最初的任务。

1 个回答

0

问题在于你把两个请求处理器同时绑定到了同一个请求上。我不太确定动态创建处理器类是不是个好主意,但如果你想这么做,可以把你的工厂函数(它本身不是请求处理器)传给网址路由表。路由表其实不一定需要一个请求处理器的子类,它只需要一个可以用 (app, request) 调用的对象,并且能返回一个请求处理器实例。

撰写回答