WebSocket握手图解:
建立连接的步骤:
- pom文件中添加依赖
- 创建握手拦截器
- 创建WebSocket处理类
- 配置WebSocket
- 前端页面访问
项目目录结构:
1.pom文件中添加依赖
<!-- springboot websocket -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2.创建握手拦截器
用于进行握手之前和握手之后的操作
一般用于握手之前将用户信息交给WebSocketSession管理
之后可以在WebSocket处理类中获取用户信息
package com.ahut.websocket;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;
/**
*
* @ClassName: MyWebSocketInterceptor
* @Description: 创建握手 此类用来获取登录用户信息并交由websocket管理
* @author cheng
* @date
/**
* HandshakeInterceptor WebSocket握手请求的拦截器. 检查握手请求和响应, 对WebSocketHandler传递属性
*/
public class MyWebSocketInterceptor implements HandshakeInterceptor
private Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* 在握手之前执行该方法, 继续握手返回true, 中断握手返回false. 通过attributes参数设置WebSocketSession的属性
*/
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
Map<String, Object> attributes) throws Exception {
logger.info("xxx用户建立连接。。。");
if (request instanceof ServletServerHttpRequest) {
String userId = ((ServletServerHttpRequest) request).getServletRequest().getParameter("userId");
attributes.put("userId", userId);
logger.info("用户唯一标识:" + userId);
}
return true;
}
/**
* 在握手之后执行该方法. 无论是否握手成功都指明了响应状态码和相应头.
*/
@Override
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
Exception exception) {
}
}
3.创建WebSocket处理类
处理类的层级关系:
package com.ahut.websocket;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
/**
*
* @ClassName: WebSocketPushHandler
* @Description: 创建处理器
* @author cheng
* @date
public class WebSocketPushHandler extends TextWebSocketHandler
private Logger logger = LoggerFactory.getLogger(this.getClass());
private static final List<WebSocketSession> userList = new ArrayList<>();
/**
* 用户进入系统监听
*/
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
logger.info("xxx用户进入系统。。。");
logger.info("用户信息:" + session.getAttributes());
Map<String, Object> map = session.getAttributes();
for (String key : map.keySet()) {
logger.info("key:" + key + " and value:" + map.get(key));
}
userList.add(session);
}
/**
* 处理用户请求
*/
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
logger.info("系统处理xxx用户的请求信息。。。");
}
/**
* 用户退出后的处理
*/
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
if (session.isOpen()) {
session.close();
}
userList.remove(session);
logger.info("xxx用户退出系统。。。");
}
/**
* 自定义函数
* 给所有的在线用户发送消息
*/
public void sendMessagesToUsers(TextMessage message) {
for (WebSocketSession user : userList) {
try {
// isOpen()在线就发送
if (user.isOpen()) {
user.sendMessage(message);
}
} catch (IOException e) {
e.printStackTrace();
logger.error(e.getLocalizedMessage());
}
}
}
/**
* 自定义函数
* 发送消息给指定的在线用户
*/
public void sendMessageToUser(String userId, TextMessage message) {
for (WebSocketSession user : userList) {
if (user.getAttributes().get("userId").equals(userId)) {
try {
// isOpen()在线就发送
if (user.isOpen()) {
user.sendMessage(message);
}
} catch
4.配置WebSocket
package com.ahut.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.server.HandshakeInterceptor;
import com.ahut.websocket.MyWebSocketInterceptor;
import com.ahut.websocket.WebSocketPushHandler;
/**
*
* @ClassName: WebSocketConfig
* @Description: websocket配置类
* @author cheng
* @date
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer
/**
* 注册WebSocket处理类
*/
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(createWebSocketPushHandler(), "/webSocketServer")
.addInterceptors(createHhandshakeInterceptor()).setAllowedOrigins("*");
registry.addHandler(createWebSocketPushHandler(), "/sockjs/webSocketServer")
.addInterceptors(createHhandshakeInterceptor()).withSockJS();
}
/**
*
* @Title: createHhandshakeInterceptor
* @Description: 握手拦截器
* @return
@Bean
public HandshakeInterceptor createHhandshakeInterceptor() {
return new MyWebSocketInterceptor();
}
/**
*
* @Title: createWebSocketPushHandler
* @Description: 处理类
* @return
@Bean
public WebSocketHandler createWebSocketPushHandler() {
return new
5.前端页面访问
<!DOCTYPE html>
<html>
<head>
<title>Java后端WebSocket的Tomcat实现</title>
</head>
<body>
Welcome<br/><input id="text" type="text"/>
<button onclick="send()">发送消息</button>
<hr/>
<button onclick="closeWebSocket()">关闭WebSocket连接</button>
<hr/>
<div id="message"></div>
</body>
<script type="text/javascript">var websocket = null;
//判断当前浏览器是否支持WebSocket
if ('WebSocket' in window) {
websocket = new WebSocket("ws://localhost:8080/webSocketServer?userId=wrwefesdfwetrwe324324");
}
else {
alert('当前浏览器 Not support websocket')
}
//连接发生错误的回调方法
websocket.onerror = function ()
setMessageInnerHTML("WebSocket连接发生错误");
};
//连接成功建立的回调方法
websocket.onopen = function ()
setMessageInnerHTML("WebSocket连接成功");
}
//接收到消息的回调方法
websocket.onmessage = function (event)
setMessageInnerHTML(event.data);
}
//连接关闭的回调方法
websocket.onclose = function ()
setMessageInnerHTML("WebSocket连接关闭");
}
//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function ()
closeWebSocket();
}
//将消息显示在网页上
function setMessageInnerHTML(innerHTML)
document.getElementById('message').innerHTML += innerHTML + '<br/>';
}
//关闭WebSocket连接
function closeWebSocket()
websocket.close();
}
//发送消息
function send()
var message = document.getElementById('text').value;
websocket.send(message);
}
</script>
</html>
打开页面后台日志打印结果: