WebSocket
2024-06-17 19:46:49

WebSocket

概述

WebSocket是一种在单个TCP连接上进行全双工通信的协议。HTTP协议有一个缺陷,即通信只能由客户端发起,如果服务器有状态变化,只能通过客户端轮询每隔一段时间给服务端发起请求,询问是否有新消息。而WebSocket协议中,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息。

img

WebSocket协议由两部分组成

  • 握手
  • 数据传输

握手

握手是基于http协议的。

来自客户端的握手

1
2
3
4
5
6
7
GET ws://localhost/char HTTP/1.1
HOST: localhost
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-key: key1
Sec-WebSocket-Extensions: permessage-deflate
Sec-WebSocket-Version: 13

来自服务器的握手

1
2
3
4
5
HTTP/1.1 101 Switching Protocols
Upgrade: webscocket
Connection: Upgrade
Sec-WebSocket-Accept: acc1
Sec-WebSocket-Extensions: permessage-deflate

字段说明

头名称 说明
Connection: Upgrade 标识该HTTP请求是一个协议升级请求
Upgrade: websocket 协议升级为WebScoket协议
Sec-WbSocket-Versions: 13 客户端支持WebSocket的版本
Sec-WbSocket-key: xxx 客户端采用base64编码的24位随机字符序列,服务器接受客户端HTTP协议升级的证明。要求服务端响应一个对应的加密的Sec-WebSocket-Accept头信息作为应答
Sec-WbSocket-Extensions: permessage-deflate 协议拓展类型

客户端(浏览器)实现

WebSocket对象

1
var ws = new WebSocket(url)

通过上面的语句创建一个WebSocket对象,需要传入参数url

url:ws://ip:prot/resources

WebSocket事件

事件 事件处理程序 描述
open websocket.onopen 连接建立时触发
message websocket.onmessage 客户端接收服务端数据时触发
error websocket.onerror 通信发生错误时触发
close websocket.onclose 连接关闭时触发

WebSocket方法

方法 描述
send() 使用连接发送数据

服务端实现

Tomcat的7.0.5版本开始支持WebSocket协议,并且实现了Java WebSocket规范

Java WebSocket应用有一系列的WebSocketEndpoint组成。EndPoint是一个Java对象,代表WebSocket连接的一端。

两种方式定义EndPoint

  • 编程式:继承类javax.websocket.EndPoint并实现方法
  • 注解式:定义一个POJO,并添加@ServerEndpoint相关注解

服务端接受客户端发送的数据

通过为Session添加MessageHandler消息处理器来接受消息,当采用注解方式时,通过注解@OnMessage注解指定接受消息的方法。

服务端推送数据给客户端

发送消息由RemoteEndPoint完成,其实例由Session维护。根据使用情况,可以通过Session.getBasicRemote获取发送同步消息的实例,调用sendXxx()方法发送消息;可以通过Session.getAsyncRemote获取发送异步消息的实例