Juubes
Juubes

Reputation: 23

How to Complete a WebSocket Handshake?

I'm making a website with a game on it. For the game i need to send data trought sockets. Everything is working fine with loading the page but I can't get the handshaking to work.

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

The socketReq variable is there because I don't want anyone to connect to localhost:25580 straight from their browser. My send and receive functions are in different Threads and they will be started after the handshake.

The result of new WebSocket("ws://localhost:25580") in JS is

WebSocket connection to 'ws://localhost:25580/' failed: Error during WebSocket handshake: net::ERR_CONNECTION_CLOSED

I was having

Error during WebSocket handshake: Incorrect 'Sec-WebSocket-Accept' header value

but I guess I changed something in the code.

I searched for hours trought Article 1 and Article 2 and from other sites. Just couldn't get the whole thing to work properly.

I don't get the point of the keys and why we have to encode them.

The socket is connected to the browser and I am getting the headers from it.

Host: localhost:25580

Sec-WebSocket-Key: iWLnXKrA3fLD6h6UGMIigg==

How does the handshaking work?

Upvotes: 0

Views: 9229

Answers (2)

gre_gor
gre_gor

Reputation: 6807

You are getting a net::ERR_CONNECTION_CLOSED error, because you are closing the connection with output.close().

If you want to keep the connection open, obviously don't close it during a handshake.

Upvotes: 1

Juubes
Juubes

Reputation: 23

Done!

Found the answers from http://blog.honeybadger.io/building-a-simple-websockets-server-from-scratch-in-ruby/ and It's working perfectly!

The 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);
}

Now I just have to decode the messages.

Upvotes: 0

Related Questions