【问题标题】:How to access Autobahn WebSocketResource from Twisted Root Resource?如何从 Twisted Root 资源访问 Autobahn WebSocket 资源?
【发布时间】:2017-07-08 00:00:19
【问题描述】:

我一直在搜索许多示例来演示如何访问 Autobahn Twisted WebSocketResource ,但似乎找不到显示这一点的示例。

我从这个例子Autobahn Twisted WebSocketResource example了解到,你实例化了一个WebSocketServerFactory,设置了websocket协议,然后使用WebSocketResource(factory)创建了websocket资源。拥有 websocket 资源后,可以在创建 Site 实例之前将其添加到主 Twisted Web 资源路径中,如下所示:

class WebSocketProtocol(WebSocketServerProtocol):

    def onConnect(self, request):
        print("WebSocket connection request: {}".format(request))

    def onMessage(self, payload, isBinary):
        self.sendMessage(payload, isBinary)

class HttpResource(resource.Resource):
    isLeaf = True

    def render_GET(self, request):
        return "<html><h1>Hello World!</h1></html>"

factory = WebSocketServerFactory(u"ws://127.0.0.1:8000")
factory.protocol = WebSocketProtocol
ws_resource = WebSocketResource(factory)

root = HttpResource()
root.putChild(b"ws", ws_resource)

site = Site(root)

所以我的理解是ws://127.0.0.1:8000/ws 上的所有请求都将被路由到 websocket 资源。但是,浏览器似乎没有发现 /ws 资源。 GET 请求工作正常,但 websocket 请求不能。

就 websocket 请求而言,这是我认为应该解决此问题的事件流(我只是不确定如何实现它们):

  1. 浏览器向标头中的 websocket 发送带有 UpgradeGET 请求。
  2. HttpResource 上的 render_GET 方法需要在请求中识别这一点并将响应代码设置为 101 和/或定位 ws 资源以处理数据通信。

如何从根资源切换到子资源,让websocket能够处理websocket请求?

我最初的想法是在根资源上使用getChild 方法来检查ws。如果名称是ws,则返回 websocket 资源。我还在这里读到:Twisted Web (isLeaf) 根资源类HttpResource 下的isLeaf 属性不能存在,或者您无法访问根资源上的子项。

任何帮助都会很棒。非常感谢您提供的任何帮助。

干杯!

布赖恩

【问题讨论】:

    标签: python websocket twisted autobahn twisted.web


    【解决方案1】:

    在阅读了一段时间关于 Autobahn 和 Twisted 的文章后,我得到了一个有效的代码。 Autobahn 的 onConnect 方法会处理请求并在需要时将峰值放入标头中。

    class WebSocketProtocol(WebSocketServerProtocol):
    
        def onConnect(self, request):
            custom_header = {}
    
            if request.headers['sec-websocket-key']:
                custom_header['sec-websocket-protocol'] = 'graphql-ws'
            return (None, custom_header)
    
        def onMessage(self, payload, isBinary):
            self.sendMessage(payload, isBinary)
    
    class HttpResource(Resource):
        isLeaf = True
    
        def render_GET(self, request):
            return "<html><h1>Hello World!</h1></html>"
    
    factory = WebSocketServerFactory()
    factory.protocol = WebSocketProtocol
    ws_resource = WebSocketResource(factory)
    
    root = Resource()
    root.putChild("", HttpResource())
    root.putChild(b"ws", ws_resource)
    
    site = Site(root)
    reactor.listenTCP(8000, site)
    
    reactor.run()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-06
      • 1970-01-01
      • 1970-01-01
      • 2012-05-11
      相关资源
      最近更新 更多