So, I'm trying to parse a website which uses websocket to send data to clients. From what I've read:
I understood that for creating a connection, I need to send a special http request to server and ot will retrieve some data which i use to access the channel.
What I've done:
created the http request
`URL obj = new URL(url); HttpURLConnection con = (HttpURLConnection) obj.openConnection(); // optional default is GET con.setRequestMethod("GET"); //add request header con.setRequestProperty("Cache-Control", "no-cache"); con.setRequestProperty("Host", "www.example.com"); con.setRequestProperty("Upgrade", "websocket"); con.setRequestProperty("Connection", "upgrade"); con.setRequestProperty("Origin", "https://example.com"); con.setRequestProperty("Sec-WebSocket-Extensions", "x-webkit-deflate-frame"); con.setRequestProperty("Sec-WebSocket-Key", "QkWkChtTGpaZL5PkOMaRtg=="); con.setRequestProperty("Sec-WebSocket-Version", "13"); con.setRequestProperty("User-Agent", "Mozilla/..;
`
and i read the response with code 200(not 101 which is supposed to be).
Questions:
- How do i generate Sec-Websocket-Key? (in example is taken from firebug, all headers actually)
1.1. What can be done more?
1.2. The same link from http must be used to access the websocket? only with wss instead of https?
after this I try to connect the client to server and receive messages in onMessage method.
WebSocketContainer container = ContainerProvider.getWebSocketContainer(); Session session = container.connectToServer(ClientEndpoint.class, buildCEC(), new URI("wss://async.example.com/socket.io/1/?t=" + System.currentTimeMillis()));
I tried in buildCec() to insert headers to connection to server.
ClientEndpointConfig config = ClientEndpointConfig.Builder.create().build(); Configurator conf = config.getConfigurator();
`Map<String, List<String>> headers = new HashMap<String, List<String>>(); headers.put("Connection", Arrays.asList("keep-alive", "Upgrade")); headers.put("Sec-Websocket-Extensions", Arrays.asList("x-webkit-deflate-frame")); headers.put("Sec-Websocket-key", Arrays.asList("cx36sHrtuW9HZAaB6kKa/Q==")); headers.put("Sec-Websocket-Version", Arrays.asList("13")); headers.put("Upgrade", Arrays.asList("websocket")); headers.put("User-Agent", Arrays.asList("Mozill...")); conf.beforeRequest(headers); return config;`
Questions
- Is my judgement good in case i work it out and receive 101 status code from http upgrade request?(i mean , what i do next with that details?)
- Please don't judge me, i'm at the beginning with websockets in java, and i don't know javascript too well, i want to do this client in pure java with jsr-356. I've done small examples with websockets, but i can't find anywhere a good client, with headers and a more complicated handshake.
- Is it possible to connect to an unknown server, not knowing all details?
I'm using a programatic endpoint and import javax.websocket.ContainerProvider; for dealing the websocket connection from jsr356.
Lots of topics here.
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 ownSec-WebSocket-Key
, which the client validates to confirm that the server is really WebSocket capable)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 @ServerEndpointThere are a few JSR-356 standalone clients I'm aware of.
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)