I am using Tornado Webserver and want to internally call a WebSocketHandler from a RequestHandler.
It is not possible to use the redirect /redirectHandler functionality, because the WebSocketHandler class to call ("IndexHandlerDynamic1" in the example below) will be created with a classFactory.
Using the definition of Requesthandler (here) my example looks like:
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)
If I request the related url he jumps into IndexHandlerDistributor and IndexHandlerDynamic1.initialize() is called.
But on Clientside the Browser console outputs the following error:
Error during WebSocket handshake: Unexpected response code: 200
Obviously the socket connection is not opened correctly, what's my mistake ?
EDIT:
Thanks to Ben for his help!
Sadly I still have trouble to route the user to a dynamically created class named like a url parameter. I hope you can understand my problem by having a look on my example:
app = tornado.web.Application(
[(r"/", IndexHandler)] +
[(r"/channel/(?P<channelId>[^\/]+)?", ClassFactory(channelId))]
)
How to use channelId as a parameter for my call of ClassFactory as Requesthandler?
Or is there maybe another way to dynamically change the routing of my application while the application is running? If so, i could use this way to solve my initial task.
The problem is that you're attaching two RequestHandlers to the same request. I'm not sure that dynamically creating handler classes is a great idea, but if you want to do it just pass your factory function (which is not itself a RequestHandler) to the url routing table. The routing table doesn't necessarily need a RequestHandler subclass, it just needs an object which can be called with (app, request)
and return a RequestHandler instance.