【问题标题】:twisted autobahn websocket being initialized twice with wss使用 wss 初始化两次扭曲的高速公路 websocket
【发布时间】:2016-08-24 15:54:47
【问题描述】:

我有一些使用 Twisted 实现的 websocket 协议,当我使用“ws”连接时它们工作正常,但是当我启用安全 websockets 时,__init__ 方法被调用了两次。更具体地说,它被调用一次,然后连接显然失败,调用 connectionLost,然后再次调用__init__,这次连接保持打开状态。

下面的代码就是一个例子。当我使用 wss 连接时,websocket 协议的__init__ 中的日志行被调用了两次,但普通 websocket 不会发生这种情况。

导入套接字 从日期时间导入日期时间 from twisted.internet 导入反应堆

from twisted.internet.ssl import DefaultOpenSSLContextFactory

from autobahn.twisted.websocket import WebSocketServerProtocol, WebSocketServerFactory, listenWS
import txaio

txaio.use_twisted()


CERT_KEY = "certificate.key"
CERT_PATH = "certificate.crt"


def log(msg):
    print("{}: {}".format(str(datetime.now()), msg))


class TestProtocol(WebSocketServerProtocol):
    def __init__(self):
        super(TestProtocol, self).__init__()
        log("Test protocol init")

    def connectionLost(self, reason):
        WebSocketServerProtocol.connectionLost(self, reason)
        log("Connection closed: Reason is {}".format(reason))


class TestProtocolFactory(WebSocketServerFactory):
    protocol = TestProtocol


def init_websocket_protocol(factory_cls, port):
    try:
        key, crt = CERT_KEY, CERT_PATH
        context_factory = DefaultOpenSSLContextFactory(key, crt)
        connection_string = "wss://localhost:{}".format(str(port))
        factory = factory_cls(connection_string)
        listenWS(factory, contextFactory=context_factory)
        log("Port {} bound to test websocket server".format(str(port)))
    except socket.error as e:
        log("Server was unable to bind to a new port: ".format(str(e)))


def main():
    init_websocket_protocol(TestProtocolFactory, 9000)
    reactor.run()


if __name__ == '__main__':
    main()

【问题讨论】:

    标签: python websocket twisted autobahn


    【解决方案1】:

    现在推荐的 API 是使用端点。此外,twisted.internet.ssl.CertificateOptions 是 TLS 连接的首选 API。因此,通过这些更改,您上面的代码将如下所示:

    from datetime import datetime
    from autobahn.twisted.websocket import WebSocketServerProtocol, WebSocketServerFactory
    from twisted.internet.ssl import CertificateOptions, PrivateCertificate, Certificate, KeyPair
    from twisted.internet.endpoints import SSL4ServerEndpoint
    from twisted.internet.task import react
    from OpenSSL import crypto
    
    
    CERT_KEY = "certificate.key"
    CERT_PATH = "certificate.crt"
    
    
    def log(msg):
        print("{}: {}".format(str(datetime.now()), msg))
    
    
    class TestProtocol(WebSocketServerProtocol):
        def __init__(self):
            super(TestProtocol, self).__init__()
            log("Test protocol init")
    
        def connectionLost(self, reason):
            WebSocketServerProtocol.connectionLost(self, reason)
            log("Connection closed: Reason is {}".format(reason))
    
    
    
    class TestProtocolFactory(WebSocketServerFactory):
        protocol = TestProtocol
    
    
    def init_websocket_protocol(reactor, port):
        with open(CERT_KEY) as key_file, open(CERT_PATH) as cert_file:
            key = KeyPair.load(key_file.read(), crypto.FILETYPE_PEM).original
            cert = Certificate.loadPEM(cert_file.read()).original
        ctx = CertificateOptions(
            privateKey=key,
            certificate=cert,
        )
        return SSL4ServerEndpoint(reactor, port, ctx)
    
    
    def main(reactor):
        ep = init_websocket_protocol(reactor, 9000)
        ep.listen(TestProtocolFactory())
        reactor.run()
    
    
    if __name__ == '__main__':
        react(main)
    

    当我运行此代码并将 Firefox 指向它时,它会连接一次。您使用的浏览器端代码是什么样的?

    【讨论】:

    • 我正在使用 var ws = new WebSocket("wss://localhost:9000"); 创建一个新的 websocket。我运行了这个,但我仍然遇到同样的问题,它初始化协议对象,然后关闭连接,然后再次初始化它,但这次保持打开状态。我正在添加一个 https 端点,以便我可以接受证书,但我什至在没有 https 端点的情况下重新启动了服务器,看看它是否会有所作为,但它没有。也试过用firefox,也没有让我用这段代码连接。
    • 这是自签名证书还是类似的?您可以尝试使用此代码来创建您的证书吗? github.com/crossbario/crossbarexamples/tree/master/…
    • 我知道这来得太晚了,但是,我只是尝试使用 create-self-signed-cert.sh 来创建证书,但我仍然遇到同样的错误。早在 2016 年(天哪,实际上已经好几年了)我只是添加了一堆 hasattr 检查以避免打开/关闭/再次打开的错误,但现在我们改变了一堆东西,这不再可行 =/
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多