2017-11-21 2 views
0

Ich entwickle WebSocket Server mit Netty Frame Arbeit Version 4.1.6. ich von netty example site den Beispielcode verwenden Dieser mein Server-Quellcode:sichere Websocket Verbindung zwischen Javascript Client und Netty Server

public class WebSocketServer 
{ 
    static final int PORT = 4466; 
    public static void main(String[] args) 
    { 
     final SslContext sslCtx; 
     EventLoopGroup bossGroup = new NioEventLoopGroup(1); 
     EventLoopGroup workerGroup = new NioEventLoopGroup(); 

     try { 
      SelfSignedCertificate ssc = new SelfSignedCertificate(); 
      sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build(); 
      ServerBootstrap b = new ServerBootstrap(); 
      b.group(bossGroup, workerGroup) 
       .channel(NioServerSocketChannel.class) 
       .handler(new LoggingHandler(LogLevel.INFO)) 
       .childHandler(new WebSocketServerInitializer(sslCtx)); 

      Channel ch = b.bind(PORT).sync().channel(); 

      System.out.println("Open your web browser and navigate to " + 
        "http://127.0.0.1:" + PORT + '/'); 

      ch.closeFuture().sync(); 
     } catch (Exception e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } finally { 
      bossGroup.shutdownGracefully(); 
      workerGroup.shutdownGracefully(); 
     } 

    } 

} 

Einen WebSocketServerInitializer Quellcode:

public class WebSocketServerInitializer extends ChannelInitializer<SocketChannel> 
{ 
    private static final String WEBSOCKET_PATH = "/websocket"; 
    private final SslContext sslCtx; 
    public WebSocketServerInitializer(SslContext sslCtx) { 
     this.sslCtx = sslCtx; 
    } 
    @Override 
    public void initChannel(SocketChannel ch) throws Exception { 
     ChannelPipeline pipeline = ch.pipeline(); 
     pipeline.addLast(sslCtx.newHandler(ch.alloc())); 
     pipeline.addLast(new HttpServerCodec()); 
     pipeline.addLast(new HttpObjectAggregator(65536)); 
     pipeline.addLast(new WebSocketServerCompressionHandler()); 
     pipeline.addLast(new WebSocketServerProtocolHandler(WEBSOCKET_PATH, null, true)); 
     // pipeline.addLast(new WebSocketIndexPageHandler(WEBSOCKET_PATH)); 
     pipeline.addLast(new WebSocketFrameHandler()); 
    } 
} 

Das ist mein HTML-Code:

<html> 
    <head> 

     <script type="text/javascript"> 
     // Let us open a web socket 
     var ws = null; 
     function WebSocketTest() 
     { 
      if ("WebSocket" in window) 
      { 
       alert("WebSocket is supported by your Browser!"); 

       // Let us open a web socket 
       ws = new WebSocket("wss://localhost:4466/websocket"); 
       ws.onopen = function() 
       { 
        // Web Socket is connected, send data using send() 
        ws.send("Message to send"); 
        alert("Message is sent..."); 
       }; 

       ws.onmessage = function (evt) 
       { 
        var received_msg = evt.data; 
        alert(received_msg); 
        //alert("Message is received..."); 
       }; 

       ws.onclose = function() 
       { 
        // websocket is closed. 
        alert("Connection is closed..."); 
       }; 

       window.onbeforeunload = function(event) { 
        socket.close(); 
       }; 
      } 

      else 
      { 
       // The browser doesn't support WebSocket 
       alert("WebSocket NOT supported by your Browser!"); 
      } 
     } 
     </script> 

    </head> 
    <body> 

     <div id="sse"> 
     <a href="javascript:WebSocketTest()">Run WebSocket</a> 
     </div> 
    </body> 
</html> 

I Durchsuchen Sie die Seite mit dem Chrome-Browser und erhalten Sie die folgende Meldung, wenn ich auf den Link auf der Webseite klicke.

WebSocket-Verbindung zu 'WSS: // localhost: 4466/websocket' ist fehlgeschlagen: Fehler beim Verbindungsaufbau: net :: ERR_INSECURE_RESPONSE

Nach einigen Diskussionen hier, und der netty websocket Beispielcode, wss muss von HTTPS weitergeleitet werden. Allerdings, wenn ich die folgende JavaScript-Anweisung in meiner Web-Seite ändern:

ws = new WebSocket("wss://localhost:4466/websocket"); 

zu

ws = new WebSocket("wss://echo.websocket.org"); 

Es funktioniert gut. Es macht mich verwirrend, warum die Seite echo.websocket.org ohne https funktionieren kann? Warum kann mein Server nicht? fehlt etwas in meinem Serverquellcode?

PS: das echo.websocket.org Beispiel in der folgenden URL gefunden:

http://jsbin.com/muqamiqimu/edit?js,console

Antwort

0

Ihr Browser auf Ihren websocket Server verbinden versagt, weil sie erkannt es unsicher ist.

Dies passiert, wenn der Browser versucht, eine Verbindung zu Ihrem Server herzustellen, wird das SSL-Zertifikat überprüft. Dieses Zertifikat ist im Grunde ein Beweis dafür, dass Ihr Server behauptet, der autoritative Server für localhost zu sein.

Ihr Server behauptet dies durch sein Zertifikat, was in Ihrem Fall von sich selbst unterzeichnet ist, das ist im Grunde die SelfSignedCertificate Klasse, und es behauptet, "example.com" zu sein.

Dies schafft zwei Probleme:

  • Ihr Browser eine Verbindung zu localhost, sondern ein Zertifikat für localhost zu bekommen, es wird 1 für example.com
  • Ihr Browser den Unterzeichner des Zertifikats nicht vertraut zu haben die Befugnis, Zertifikate zu erstellen, wodurch diese abgelehnt wird.

Es gibt mehrere Möglichkeiten, dieses Problem zu lösen:

Erste ein gültiges Zertifikat und das Hosting Ihrer Anwendung auf einem Server

Dies wäre die empfohlene Lösung für die Produktion, je nachdem, wo Sie Ihr gültiges Zertifikat erhalten, Es kann Geld kosten oder nicht.

Bypass das Zertifikat Warnung

Durch manuell http://localhost:4466/ gehen Sie vorbei an der Zertifikatswarnung überspringen kann, und im Grunde fügt dies eine 1mal Ausnahme für das Zertifikat der Regel, bis Sie Ihren Browser neu starten

Google Chrome konfigurieren Ungültige Zertifikate für localhost annehmen

Obwohl dies unsicher sein kann (aber nicht so unsicher wie das Ausschalten der Zertifikatsprüfung), kann es eine gute Möglichkeit sein, SSL auf Entwicklungsmaschinen zu testen.

Sie können ssl-Validierung von für localhost drehen, indem Sie zu chrome: // flags/# allow-unsecure-localhost gehen und diese Option aktivieren. Beachten Sie, dass Sie möglicherweise die Domäne Ihres Zertifikats auf localhost festlegen müssen, wenn Sie diese Option verwenden, indem Sie den new SelfSignedCertificate("localhost");-Konstruktor aufrufen.

+0

danke für Ihre Erklärung. –

Verwandte Themen