2016-07-29 6 views

答えて

0

HTTPページとWebソケットの要求の違いは、ヘッダーが存在することです。残念ながらafaikには、竜巻ルーターにヘッダー(ホスト以外)に基づいて1つまたは他のハンドラーを選択させる方法がありません。

しかし私はすでにかなり精巧なMyBaseRequestHandlerWebSocketHandlerの両方を継承し、いくつかの魔法を使ってハンドラを作ることができます。次のコードはpython 3.5とtornado 4.3で動作しますが、あなたの走行距離は他のバージョンと異なる場合があります:

class WebSocketHandlerMixin(tornado.websocket.WebSocketHandler): 
    def __init__(self, *args, **kwargs): 
     super().__init__(*args, **kwargs) 
     # since my parent doesn't keep calling the super() constructor, 
     # I need to do it myself 
     bases = type(self).__bases__ 
     assert WebSocketHandlerMixin in bases 
     meindex = bases.index(WebSocketHandlerMixin) 
     try: 
      nextparent = bases[meindex + 1] 
     except IndexError: 
      raise Exception("WebSocketHandlerMixin should be followed " 
          "by another parent to make sense") 

     # undisallow methods --- t.ws.WebSocketHandler disallows methods, 
     # we need to re-enable these methods 
     def wrapper(method): 
      def undisallow(*args2, **kwargs2): 
       getattr(nextparent, method)(self, *args2, **kwargs2) 
      return undisallow 

     for method in ["write", "redirect", "set_header", "set_cookie", 
         "set_status", "flush", "finish"]: 
      setattr(self, method, wrapper(method)) 
     nextparent.__init__(self, *args, **kwargs) 

    async def get(self, *args, **kwargs): 
     if self.request.headers.get("Upgrade", "").lower() != 'websocket': 
      return await self.http_get(*args, **kwargs) 
     # super get is not async 
     super().get(*args, **kwargs) 


class MyDualUseHandler(WebSocketHandlerMixin, MyBaseHandler): 
    def http_get(): 
     self.write("My HTTP page") 

    def open(self, *args, **kwargs): 
     self.write_message("Hello WS buddy") 

    def on_message(self, message): 
     self.write_message("I hear you: %s" % message) 
関連する問題