WebSocket
WebSocket介绍
web Socket 是一种网络通讯协议, RFC6455定义了它的通信标准
websocket是HTML5 开始提供的一种在单个TCP 连接上进行全双工通讯的协议。
HTTP 协议是一种无状态的、无连接的、单向的应用层协议。它采用了请求/响应模型。通信请求只能由客户端发起,服务端对请求做出应答处理。
这种通信模型有一个弊端: HTTP 协议无法实现服务器主动向客户端发起消息。这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。大多数Web应用程序将通过频繁的异步AJAX 请求实现长轮询。轮询的效率低,非常浪费资源(因为必须不停连接,或者HTTP 连接始终打开)
http协议:
WebSocket : 可以主动发送消息给客户端
WebSocket协议:
协议由两部分:握手和数据传输
-
握手基于Http协议
客户端握手协议
GET ws://1ocalhost/chat HTTP/1.1 Host: local host Upgrade: websocket #connection升级为websocket连接 Connection: Upgrade # 升级链接 Sec-websocket-Key: dGh1 IHNhbXBSZSBub25jZQ== Sec-web socket-Extensions: permessage-deflate Sec-websocket-Version: 13
服务端握手协议
HTTP/1.1 101 switching Protocols #101说明websocket链接建立成功 Upgrade: websocket Connection: Upgrade Sec-websocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+XO0= Sec-websocket-Extensions: permessage-deflate
Connection: Upgrade | 标识该HTTP请求是一个协议升级请求 |
Upgrade:WebSocket | 协议升级为WebSocket 协议 |
Sec-WebSocketVersion: 13 | 客户端支持WebSocket版本 |
Sec-WebSocketKey: | 客户端采用base64编码的24位随机字符序列,服务器接受客户端HTTP协议升级的证明。要求服务端响应一个对应加密的Sec-Websocket-Accept头信息作为应答 |
Sec-WebsocketExtensions | 协议扩展类型 |
客户端(浏览器)实现
1.webSocket对象
实现WebSockets的Web 浏览器将通过webSocket 对象公开所有必需的客户端功能(主要指支持Htm15 的浏览器)以下API用于创建 WebSocket 对象:
var ws = new WebSocket(url);
参数ur1格式说明: ws://ip地址:端口号/WebSocket资源名称
2.webSocket事件
WebSocket对象的相关事件
事件 | 事件处理程序 | 描述 |
open | websocket对象.onopen | 连接建立时触发 |
message | websocket对象.onmessage | 客户端接收服务端数据时触发 |
error | websocket对象.onerror | 通信发生错误时触发 |
close | websocket对象.onclose | 连接关闭时触发 |
3.webSocket方法
方法 | 描述 |
send() | 使用连接发送数据 |
服务端实现
Tomcat的7.0.5 版本开始支持websocket,并且实现了Java websocket规范(JSR356)。
Java WebSocket应用由一系列的websocketEndpoint组成。Endpoint是一个java对象,代表websocket链接的一端,对于服务端,我们可以视为处理具体webSocket消息的接口,就像Servlet之与http请求一样。
我们可以通过两种方式定义Endpoint:
-
第一种是编程式, 即继承类javax.websocket.Endpoint并实现其方法。
-
第二种是注解式,即定义一个POJO,并添加@ServerEndpoint相关注解。
Endpoint实例在webSocket握手时创建,并在客户端与服务端链接过程中有效,最后在链接关闭时结束。在Endpoint接口中明确定义了与其生命周期相关的方法,规范实现者确保生命周期的各个阶段调用实例的相关方法。生命周期方法如下:
方法 | 描述 | 注解 |
onClose | 当会话关闭时调用 | @OnClose |
onOpen | 当开启一个新的会话时调用,该方法时客户端与服务端握手成功后调用的方法 | @OnOpen |
onError | 当连接过程中异常时调用 | @OnError |
服务端如何接受客户端发送的数据
通过为Session添加MessageHandler消息处理器来接收消息,当采用注解方式定义Endpoint时,我们还可以通过@OnMessage注解指定接收消息的方法。
发送消息则由RemoteEndpoint完成,其实例由session维护,根据使用情况,我们可以通过Session.getBasicRemote 获取同步消息发送的实例 , 然后调用其 sendxxx()方法就可以发送消息,可以通过Session.getAsyncRemote获取异步消息发送实例。