Search code examples
javawebsocketoutputstreamflushno-data

Java WebSocket server OutputStream not flushing


I have read a similar question, but my problem wasn't solved.

I am trying, for the sake of learning, to build my own Java WebSocket server. The server is set up fine, it accepts incoming connections and gets the handshake data from the client. My server then calculates the handshake return data and tries to write it and flush it. Nonetheless, the in the web inspector, no response headers are shown for the client and the onopen-JavaScript event is never fired.

String EOL = System.getProperty("line.separator"); // actually a class-defined constant

BufferedReader inputStream = currentClient.getInputStream();
OutputStream outputStream = currentClient.getOutputStream();

String inputLine;
String handshake = "";

try {

    if(!inputStream.ready()){ continue; }

    System.out.println("Receiving:\n");

    while ((inputLine = inputStream.readLine()).length() > 0) {

        if(inputLine.startsWith("Sec-WebSocket-Key: ")){

            String inputKey = inputLine.replace("Sec-WebSocket-Key: ", "");
            String outputKey = WebSocket.getWebSocketKey(inputKey);

            handshake += "HTTP/1.1 101 Switching Protocols"+EOL;
            handshake += "Upgrade: websocket"+EOL;
            handshake += "Connection: Upgrade"+EOL;
            handshake += "Sec-WebSocket-Accept: "+outputKey;

        }

        System.out.println(inputLine);

    }

} catch (Exception e) {

    e.printStackTrace();

}

System.out.println("\n\nSending:\n");

System.out.println(handshake);
try {
    outputStream.write(handshake.getBytes(Charset.forName("UTF-8")));
    outputStream.flush();
} catch (IOException e) {
    e.printStackTrace();
}

So here's an example of what I get:

GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: localhost:65432
Origin: http://localhost
Sec-WebSocket-Key: ph1CO1PCF60uojeP+nql5A==
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: x-webkit-deflate-frame

And what I try to send:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: Z2Vy9p7Lp+MZPdZOe+L5GhVBDpc=

I'd like to note that sending the headers I send ought to be sufficient, since in a PHP WebSocket server I developed, sending no more than these headers DOES work.


Solution

  • A websocket handshake is a HTTP request followed by a HTTP response. RFC2616 states that the end-of-line marker for HTTP is CRLF ("\r\n").

    HTTP requests end with a double newline ("\r\n\r\n" - see section 4 of the RFC); the websocket handshake response is a HTTP response so also needs to end like this.