2016-08-24 4 views
0

Ich habe einige Websocket-Protokolle mit Twisted implementiert, sie funktionieren gut, wenn ich mit "ws" verbinden, aber wenn ich sichere websockets aktivieren, wird die __init__ Methode zweimal aufgerufen. Genauer gesagt, es wird einmal aufgerufen, dann schlägt die Verbindung scheinbar fehl, wobei connectionLost aufgerufen wird, dann wird die __init__ erneut aufgerufen, und dieses Mal bleibt die Verbindung offen.twisted autobahn websocket wird zweimal mit wss initialisiert

Der Code unten veranschaulicht es. Wenn ich mich mit wss verbinde, wird die Protokollzeile in der __init__ des Websocket-Protokolls zweimal aufgerufen, aber das passiert nicht bei einfachen Websockets.

import Buchse aus DATETIME import DATETIME aus twisted.internet import Reaktor

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() 

Antwort

2

Die in diesen Tagen empfohlen API ist Endpunkte zu verwenden. Außerdem ist twisted.internet.ssl.CertificateOptions die bevorzugte API für TLS-Verbindungen. Also mit diesen Änderungen über Ihren Code würde wie folgt aussehen:

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) 

Wenn ich diesen Code ausführen und zeige Firefox daran, es einmal verbindet. Wie sieht der browserseitige Code aus, den Sie verwenden?

+0

Ich erstelle einen neuen Websocket mit 'var ws = neuer WebSocket (" wss: // localhost: 9000 ");'. Ich habe das ausgeführt, aber ich habe immer noch das gleiche Problem, es initialisiert das Protokoll-Objekt, dann schließt die Verbindung, als es wieder initialisiert, aber diese Zeit bleibt offen. Ich füge einen https-Endpunkt hinzu, damit ich das Zertifikat akzeptieren kann, aber ich habe sogar den Server ohne den https-Endpunkt neu gestartet, um zu sehen, ob es einen Unterschied machen würde, aber nicht. Auch mit Firefox versucht, ließ mich überhaupt nicht mit diesem Code verbinden. –

+0

Dies ist ein selbstsigniertes Zertifikat oder ähnliches? Können Sie versuchen, diesen Code zum Erstellen Ihrer Zertifikate zu verwenden? https://github.com/crossbario/crossbarexamples/tree/master/authentication/tls/static – meejah

Verwandte Themen