如何从Twisted Root Resource访问Autobahn WebSocketResource?

时间:2017-07-08 00:00:20

标签: python websocket twisted autobahn twisted.web

我一直在寻找许多示例来演示如何访问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. 浏览器向GET发送Upgrade请求到标题中的websocket。
  2. {li} render_GET方法需要在请求中识别此问题,并将响应代码设置为101和/或找到HttpResource资源以处理数据通信。

    如何从根资源切换到子资源,以便websocket可以处理websocket请求?

    我最初的想法是使用根资源上的ws方法来检查getChild。如果name为ws,则返回websocket资源。我还在此处阅读:Twisted Web (isLeaf)根资源类ws下的isLeaf属性不能出现,或者您无法访问根资源上的子项。

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

    干杯!

    布赖恩

1 个答案:

答案 0 :(得分:0)

在阅读了有关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()