2016-08-24 4 views
0

Twistedで実装されたwebsocketプロトコルがいくつかありますが、 "ws"で接続すると正常に動作しますが、安全なWebソケットを有効にすると__init__メソッドが2回呼び出されます。具体的には、一度呼び出されるとconnectionLostが呼び出されて接続が失敗し、__init__が再び呼び出され、今回は接続が開いたままになります。wsで2回初期化されたautobahn websocketのねじれ

以下にコード例を示します。 wssに接続すると、websocketプロトコルの__init__のログ行が2回呼び出されますが、これはプレーンなWebソケットでは発生しません。これらの日は、エンドポイントを使用することです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() 

答えて

2

お勧め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をポイントすると、一度接続されます。使用しているブラウザ側のコードはどのように見えますか?

+0

私は 'var ws = new WebSocket(" wss:// localhost:9000 ");'で新しいwebsocketを作成しています。私はこれを走らせましたが、私は同じ問題を抱えています、それはプロトコルオブジェクトを初期化し、接続を閉じるよりも、それを再び初期化するよりも、この時間は開いたままです。 私は証明書を受け入れることができるようにhttpsエンドポイントを追加していますが、HTTPSエンドポイントを使わずにサーバーを再起動しても、違いがあるかどうかはわかりますが、変更はありません。 また、Firefoxで試してみましたが、このコードでも接続することはできませんでした。 –

+0

これは自己署名入りの証明書ですか?これは似ていますか?このコードを使用して証明書を作成できますか? https://github.com/crossbario/crossbarexamples/tree/master/authentication/tls/static – meejah

関連する問題