Websocket
简单来说websocket实现了双向通信,即服务端可以主动发送消息给客户端,客户端也可以主动发送消息给服务端
·
Websocket与HTTP的区别
● websocket中可以双向通信服务器端可以主动给客户端发送消息,http只能客户端主动给服务端发送消息
● http客户端与服务端的通信必须建立在request和response,且一条response对应一条request
● websocket在连接时运用到了http中的tcp协议进行三次握手连接
● websocket是可持续状态的连接,而http是无状态连接
·
Websocket与HTTP各自的优势
● 在客户端与服务端进行一段持续的会话时用websocket更好。如开启会话,监控,历史回放等
● 在客户端与服务端只需进行短暂的交互时用HTTP消耗的资源更少也更方便。如用户登录,查看数据页面等
·
Websocket测试网址
http://websocket.org/echo.html
·
Websocket生命周期及代码实例
后端
@onOpen
public void onOpen(Session session, EndpointConfig config){
/* 当websocket连接成功后 */
}
@onClose
public void onClose(Session session, CloseReason closeReason) {
/* 当websocket发送消息发生错误时 */
}
@onError
public void onError(Session session, Throwable throwable) {
/* 当websocket连接关闭后 */
}
@onMessage
public void onMessage(String message) {
/* 接收客户端发来的消息 */
}
}
·
Websocket连接实例
后端在controller层编写websocket连接的类可继承Endpoint
@ServerEndpoint(
value = "/url",
configurator = xxxConfigurator.class // 配置类,通过配置类可以拿到初始连接时的request参数
)
@Component
public class xxx extends Endpoint{
private RemoteEndpoint.Basic remote; // websocket发送消息
private ObjectMapper objectMapper; // 可将json类型转换成字符串
@Override
public void onOpen(Session session, EndpointConfig config) {
System.out.println("连接成功");
// 通过config中可以得到初始连接时request参数
System.out.println(config.getUserProperties().get("id"));
remote = session.getBasicRemote();
// 向前端发送数据
remote.sendText(String类型数据)
remote.sendText(objectMapper.writeValueAsString(json类型的数据))
}
@OnMessage
public void onMessage(String message){
/* 从前端接收message消息 */
}
}
配置Configurator类(可通过配置此类获取request请求参数)
public class xxxConfigurator extends ServerEndpointConfig.Configurator {
@Override
public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
// 可获取request中的请求参数的集合
Map<String, List<String>> queryParam = request.getParameterMap();
// 通过getUserProperties()使得websocket连接类中可获取到配置类中得到的数据
Map<String, Object> userProperties = sec.getUserProperties();
// 以获取get请求中的id参数为例
userProperties.put("id", queryParam.get("id").get(0));
super.modifyHandshake(sec, request, response);
}
}
·
前端建立websocket连接
// 创建空数组接收数据
self.events = []
// 连接websocket
const socket = new WebSocket(`ws://localhost:8082/xxx?id=${this.$route.query.id}`)
// 从后端接收消息
socket.onmessage = event => {
// 将后端收到的json类型强转后的的字符串强转成json类型,加入到events数组中
self.events.push(JSON.parse(event.data));
}