2016-07-29 60 views

回答

0

對HTTP頁面和WebSocket的請求之間的區別是存在標題。不幸的是,afaik沒有辦法告訴龍捲風路由器根據報頭(除主機之外)選擇一個或另一個處理程序。

然而,我可以製作一個處理程序,它既繼承了我已經相當詳盡的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)