websocket协议的握手过程。
首先客户端和服务器端建立的是http 1.1的连接,客户端发送请求,请求的资源地址是websocket的地址,但在连接中增加几个请求头:
Connection: upgrade
Upgrade: Websocket
Sec-WebSocket-Key: base64格式的随机数
Sec-Websocket-Version: 13 (13是版本号)
服务器收到这种连接后,如果支持升级到websocket,会发出类似如下的回应:
HTTP/1.1 101 Switching Protocols
Server: Apache-Coyote/1.1
Upgrade: websocket
Connection: upgrade
Sec-WebSocket-Accept: OfS0wDaT5NoxF2gqm7Zj2YtetzM=
Date: Tue, 04 Sep 2018 05:46:48 GMT
之后websocket连接就建好了,双方可以通讯了,下面有段建立连接的代码,可以参考。解析websocket帧部分没有写,只是当成字符串打印出来了,因为帧中包含一些二进制的控制信息,所以打印内容会有乱码(即使消息是纯文本也有乱码,因为有部分帧的头部信息也被当成字符串打印了)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| import java.net.*; import java.io.*; public class WebsocketClient { public static void main(String[] args) throws Exception { String hostname = "localhost"; int port = 8080; try (Socket socket = new Socket(hostname, port)) { OutputStream output = socket.getOutputStream(); PrintWriter writer = new PrintWriter(output, true); writer.println("GET /chat HTTP/1.1"); writer.println("Host: " + hostname + ":" + port); writer.println("Connection: upgrade"); writer.println("Upgrade: WebSocket"); writer.println("Sec-WebSocket-Key: "AQIDBAUGBwgJCgsMDQ4PEC=" ="); writer.println("Sec-WebSocket-Version: 13"); writer.println("User-Agent: MSIE"); writer.println("Origin: http://localhost:8080/"); writer.println(); InputStream input = socket.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(input)); System.out.println("request sent..."); int i=0; while (i < 10) { if (reader.ready()){ char[] bin = new char[2048]; int len = reader.read(bin, 0, bin.length); char[] buf = new char[len]; System.arraycopy(bin, 0, buf, 0, len); System.out.println(new String(buf)); i++; } } writer.close(); output.close(); socket.close(); } catch (UnknownHostException ex) { System.out.println("Server not found: " + ex.getMessage()); } catch (IOException ex) { System.out.println("I/O error: " + ex.getMessage()); } } }
|