1

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.

Whezz
  • 85
  • 6

1 Answers1

0

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.

Ben Darnell
  • 21,844
  • 3
  • 29
  • 50
  • Thanks for your usefull suggestion! I updated my question, maybe you can give me a hint how to solve it. – Whezz Jul 31 '14 at 22:20
  • The parsed components of the url are not made available until the RequestHandler._execute method is called, so you won't be able to use them when constructing the handler instance. You can access the raw url via attributes of the request object and parse it yourself in the factory. – Ben Darnell Aug 01 '14 at 00:51
  • Great! Thanks for your help. Extracting the parameters from the raw url via attributes solved it. – Whezz Aug 01 '14 at 12:37