Websocket Handshake Failed In Java

后端 未结 2 1410
我寻月下人不归
我寻月下人不归 2021-02-11 02:58

So, I\'m trying to parse a website which uses websocket to send data to clients. From what I\'ve read:

  • Link 1
  • Link 2

I understood that for

相关标签:
2条回答
  • 2021-02-11 03:45

    Lots of topics here.

    1. Don't use URLHttpConnection for WebSocket, it manages the output/input streams based on HTTP semantics, with no handling for Upgraded Connections. Use standard Socket.
    2. Read RFC-6455: The WebSocket Protocol
    3. The Sec-WebSocket-Key is mentioned many times in RFC6455, it has 1 overall purpose, for the client to prove that it received a valid WebSocket opening handshake from the server. There's rules for the client side, and rules for the server side on what it should do with it, and how it should respond to it. (in short, its a random value that the client picks, sends to the server, the server tacks on RFC specified GUID for this step, calculates an SHA-1 hash, and responds with this hash in its own Sec-WebSocket-Key, which the client validates to confirm that the server is really WebSocket capable)
    4. Read Section 5.2. Base Framing Protocol carefully, especially the parts around the 3 forms of payload length (you MUST implement support for all 3, as there are required rules for servers to validate this)' - see other answer about this - Java Websocket Text Frame Error at length >=128?
    5. As for javax.websocket.server.ServerEndpointConfig.Configurator, those methods cannot be called by you. Those are called by the JSR-356 websocket server implementation in the process of establishing a connection. See my other answer about this process - Accessing HttpSession from HttpServletRequest in a Web Socket @ServerEndpoint
    6. Be aware of the frame validation rules - How to parse and validate a WebSocket frame in Java?

    There are a few JSR-356 standalone clients I'm aware of.

    • Eclipse Jetty 9.1+
        <dependency>
          <groupId>org.eclipse.jetty.websocket</groupId>
          <artifactId>javax-websocket-client-impl</artifactId>
          <version>9.1.0.v20131115</version>
        </dependency>
    
    • Apache Tomcat 8.0+
        <dependency>
          <groupId>org.apache.tomcat</groupId>
          <artifactId>tomcat-websocket</artifactId>
          <version>8.0.0-RC5</version>
        </dependency>
        <dependency>
          <groupId>org.apache.tomcat</groupId>
          <artifactId>tomcat-coyote</artifactId>
          <version>8.0.0-RC5</version>
        </dependency>
    
    • Project Grizzly
        <dependency>
          <groupId>org.glassfish.grizzly</groupId>
          <artifactId>grizzly-websockets</artifactId>
          <version>2.3.8</version>
        </dependency>
    
    • Glassfish Tyrus
        <dependency>
          <groupId>org.glassfish.tyrus.bundles</groupId>
          <artifactId>tyrus-standalone-client</artifactId>
          <version>1.3.3</version>
        </dependency>
    

    If you do write your own WebSocket client, be sure you test it against the Autobahn WebSocket Protocol Testsuite (everyone who write an implementation tests against this testsuite, its kinda become the de facto protocol validation suite)

    0 讨论(0)
  • 2021-02-11 03:53

    I think here is what you´ll need:

     String secAccept = sha1base64(secKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
    
     private String sha1base64(String str) {
            MessageDigest md = null;
            try {
                md = MessageDigest.getInstance("SHA-1");
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
            return Base64.encode(md.digest(str.getBytes()));
        }
    
    0 讨论(0)
提交回复
热议问题