package com.ruoyi.errand.utils;
|
|
|
import io.jsonwebtoken.Claims;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.data.redis.core.RedisTemplate;
|
|
import org.springframework.stereotype.Component;
|
|
import javax.annotation.Resource;
|
import javax.websocket.CloseReason;
|
import javax.websocket.OnClose;
|
import javax.websocket.OnOpen;
|
import javax.websocket.Session;
|
import javax.websocket.server.PathParam;
|
import javax.websocket.server.ServerEndpoint;
|
import java.io.IOException;
|
import java.util.List;
|
import java.util.Objects;
|
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.TimeUnit;
|
|
@ServerEndpoint("/ws/delivery")
|
@Component
|
public class DeliveryWebSocket {
|
|
private static ConcurrentHashMap<String, Session> deliveryPersonSessions = new ConcurrentHashMap<>();
|
|
|
private static RedisTemplate redisTemplate;
|
@Autowired
|
public void setRedisTemplate(RedisTemplate redisTemplate) {
|
DeliveryWebSocket.redisTemplate = redisTemplate;
|
}
|
|
|
@OnOpen
|
public void onOpen(Session session) {
|
// 从查询参数获取token
|
String token = session.getRequestParameterMap().get("token").stream().findFirst().orElse(null);
|
// 验证token
|
String userId=validateToken(token);
|
if (null==userId) {
|
try {
|
session.close(new CloseReason(CloseReason.CloseCodes.VIOLATED_POLICY, "Invalid token"));
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
return;
|
}
|
|
deliveryPersonSessions.put(userId, session);
|
checkPendingNotifications(userId);
|
}
|
|
private String validateToken(String token) {
|
if (token == null || !token.startsWith("app:")) {
|
return null;
|
}
|
try {
|
//解析token 获取userid,再查询到AppUser
|
String realToken = token.substring(4);
|
Claims claims = JwtUtil.parseJWT(realToken);
|
String userId = claims.get("userId").toString();
|
return userId;
|
} catch (Exception e) {
|
return null;
|
}
|
}
|
|
|
@OnClose
|
public void onClose(Session session) {
|
String token = session.getRequestParameterMap().get("token").stream().findFirst().orElse(null);
|
// 验证token
|
String userId=validateToken(token);
|
if (null==userId) {
|
try {
|
session.close(new CloseReason(CloseReason.CloseCodes.VIOLATED_POLICY, "Invalid token"));
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
return;
|
}
|
deliveryPersonSessions.remove(userId);
|
}
|
|
private void checkPendingNotifications(String userId) {
|
String key = "delivery:notification:" + userId;
|
List<Object> notifications = redisTemplate.opsForList().range(key, 0, -1);
|
if (notifications != null && !notifications.isEmpty()) {
|
for (Object notification : notifications) {
|
sendNotification(userId, notification.toString());
|
}
|
redisTemplate.delete(key);
|
}
|
}
|
|
public void sendNotification(String userId, String message) {
|
Session session = deliveryPersonSessions.get(userId);
|
if (session != null && session.isOpen()) {
|
try {
|
session.getBasicRemote().sendText(message);
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
} else {
|
// 用户不在线,存入Redis
|
String key = "delivery:notification:" + userId;
|
redisTemplate.opsForList().rightPush(key, message);
|
// 设置过期时间,比如1天
|
redisTemplate.expire(key, 1, TimeUnit.DAYS);
|
}
|
}
|
}
|