如何完成WebSocket握手?

时间:2016-11-25 20:16:01

标签: javascript java html html5 websocket

我正在建立一个有游戏的网站。对于游戏我需要发送数据tockets。加载页面一切正常,但我无法通过握手工作。

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

socketReq变量在那里,因为我不希望任何人直接从他们的浏览器连接到localhost:25580。 我的发送和接收函数在不同的线程中,它们将在握手后启动。

JS中新的WebSocket(" ws:// localhost:25580")的结果是

  

WebSocket连接到' ws:// localhost:25580 /'失败:WebSocket握手期间出错:net :: ERR_CONNECTION_CLOSED

我有

  

WebSocket握手期间出错:错误' Sec-WebSocket-Accept'标题值

但我想我在代码中改变了一些东西。

我搜索了Article 1Article 2以及其他网站的小时数。只是无法使整个事情正常运作。

我不明白钥匙的重点以及为什么要对它们进行编码。

套接字连接到浏览器,我从中获取标题。

  

主持人:localhost:25580

     

Sec-WebSocket-Key:iWLnXKrA3fLD6h6UGMIigg ==

握手是如何工作的?

2 个答案:

答案 0 :(得分:0)

完成!

找到http://blog.honeybadger.io/building-a-simple-websockets-server-from-scratch-in-ruby/的答案,并且它完美无缺!

代码:

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

现在我只需解码消息。

答案 1 :(得分:0)

您收到net::ERR_CONNECTION_CLOSED错误,因为您正在关闭与output.close()的关联。

如果你想保持连接打开,显然不要在握手时关闭它。