2016-11-25 2 views
0

Ich mache eine Website mit einem Spiel darauf. Für das Spiel muss ich Daten über Sockets senden. Alles funktioniert gut mit dem Laden der Seite, aber ich kann den Handshake nicht funktionieren.Wie beende ich einen WebSocket Handshake?

class ServerClient { 
    public ServerClient() { 
     handshake(); 
    } 

    private void handshake() { 
    try { 
     String line; 
     String key = ""; 
     boolean socketReq = false; 
     while (true) { 
      line = input.readLine(); 
      if (line.startsWith("Upgrade: websocket")) 
       socketReq = true; 
      if (line.startsWith("Sec-WebSocket-Key: ")) 
       key = line; 
      if (line.isEmpty()) 
       break; 
     } 
     if (!socketReq) 
      socket.close(); 
     String encodedKey = DatatypeConverter.printBase64Binary(
      MessageDigest.getInstance("SHA-1") 
       .digest((key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").getBytes())); 

     System.out.println(encodedKey); 
     output.println("HTTP/1.1 101 Switching Protocols"); 
     output.println("Upgrade: websocket"); 
     output.println("Connection: Upgrade"); 
     output.println("Sec-WebSocket-Accept: " + encodedKey); 
     output.flush(); 
     output.close();  // output = new PrintWriter(
          //  Socket.getOutputStream()); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 
} 

Die socketReq Variable ist da, weil ich jemand zu localhost verbinden nicht will: 25580 direkt aus ihrem Browser. Meine Sende- und Empfangsfunktionen sind in verschiedenen Threads und werden nach dem Handshake gestartet.

Das Ergebnis der neuen WebSocket ("ws: // localhost: 25580") in JS ist

WebSocket-Verbindung zu 'ws: // localhost: 25580 /' ist fehlgeschlagen: Fehler bei der WebSocket-Handshake: net :: ERR_CONNECTION_CLOSED

ich habe

Fehler bei der WebSocket-Handshake: Falsche 'Sec-WebSocket-Accept' Header-Wert

aber ich denke, ich habe etwas im Code geändert.

Ich suchte nach Stunden trought Article 1 und Article 2 und von anderen Seiten. Ich konnte das ganze Ding nicht richtig funktionieren lassen.

Ich verstehe nicht, was die Schlüssel sind und warum wir sie kodieren müssen.

Der Socket ist mit dem Browser verbunden und ich bekomme die Header von ihm.

Host: localhost: 25580

Sec-WebSocket-Key: iWLnXKrA3fLD6h6UGMIigg ==

Wie die Handshaking funktionierts?

+1

Ich würde vorschlagen, dass Sie eine vordefinierte Klasse für einen webSocket-Server in Java auswählen (es gibt viele). Es gibt viel mehr, als Sie in Ihrem Code haben. – jfriend00

+1

Das war nur der 25580 Ports Teil des Codes. Ich möchte das ohne zusätzliche Bibliotheken machen. – Juubes

Antwort

0

Fertig!

Gefunden die Antworten von http://blog.honeybadger.io/building-a-simple-websockets-server-from-scratch-in-ruby/ und es funktioniert perfekt!

Der Code:

public ClientSocket(Socket socket) { 
    try { 
     this.socket = socket; 
     this.input = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
     this.output = new PrintWriter(socket.getOutputStream()); 
     handshake(); 
} 

private void handshake() { 
    try { 
     String line; 
     String key = ""; 
     while (true) { 
      line = input.readLine(); 
      if (line.startsWith("Sec-WebSocket-Key: ")) { 
       key = line.split(" ")[1]; 
       System.out.println("'" + key + "'"); 
      } 
      if (line == null || line.isEmpty()) 
       break; 
     } 
     output.println("HTTP/1.1 101 Switching Protocols"); 
     output.println("Upgrade: websocket"); 
     output.println("Connection: Upgrade"); 
     output.println("Sec-WebSocket-Accept: " + encode(key)); 
     output.println(); 
     output.flush(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

private String encode(String key) throws Exception { 
    key += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; 
    byte[] bytes = MessageDigest.getInstance("SHA-1").digest(key.getBytes()); 
    return DatatypeConverter.printBase64Binary(bytes); 
} 

Jetzt muss ich nur die Nachrichten entschlüsseln.

0

Sie erhalten einen net::ERR_CONNECTION_CLOSED Fehler, weil Sie die Verbindung mit output.close() schließen.

Wenn Sie die Verbindung offen halten möchten, schließen Sie sie natürlich nicht während eines Handshakes.

Verwandte Themen