Websocket 应用组成
1、pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
2、Bean
@Configuration
public class WebsocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() { // 打jar包需要,打war包则不要
return new ServerEndpointExporter();
}
}
3、Endpoint
@Component
@ServerEndpoint(value = "/socket/log/{logId}")
public class LogWebSocket {
// 记录当前连接数
public static AtomicInteger onlineCount = new AtomicInteger(0);
// 存放所有连接
public static Map<String, Session> clients = new ConcurrentHashMap<>();
@OnOpen
public void onOpen(Session session) {
onlineCount.incrementAndGet(); // 连接数加1
clients.put(session.getId(), session);
String logId = session.getPathParameters().get("logId"); // 可以从Endpoint Url 中获取参数
}
@OnClose
public void onClose(Session session) {
onlineCount.decrementAndGet(); // 连接数减1
clients.remove(session.getId());
}
@OnError
public void onError(Session session, Throwable error) {
error.printStackTrace();
}
// 接收来自客户端的消息
@OnMessage
public void onMessage(String message, Session session) {
LogMessage logMessage = JSON.parseObject(message, LogMessage.class); // 把前端传来的JSON字符串转换成对象
this.sendMessage(session,"Hello");
}
private void sendMessage(Session session, String message) {
try {
session.getBasicRemote().sendText(message); // 发送消息给客户端
} catch (Exception e) {
e.printStackTrace();
}
}
}
Nginx 配置 Websocket
location ^~ /socket {
proxy_pass http://socket-service;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_connect_timeout 4s;
proxy_read_timeout 7200s;
proxy_send_timeout 12s;
}
整合 JWT
目的:对客户端进行 认证
JwtTokenUtil 参考://www.greatytc.com/p/57e50b2b1144
1、登录时 生成 token 返回给客户端
String jwt = jwtTokenUtil.generateToken(username);
2、客户端连接Websocket 时 URL带上 ?token=,服务端验证token
@OnOpen
public void onOpen(Session session) {
Map<String, List<String>> parameterMap = session.getRequestParameterMap();
String jwt = parameterMap.get("token").get(0); // 从URL参数里获取 token
String username = jwtTokenUtil.getUsernameFromToken(jwt);
if (username != null && jwtTokenUtil.validateToken(jwt, username)) { // 验证token
// 连接后的业务逻辑
}
else{
session.close();
}
}