单点登录踢下线

dev_2.0.0
liu 1 year ago
parent f380b9fc10
commit 7b522286e7

@ -56,5 +56,11 @@ public class UserController {
redisTemplate.expire(UserTokenConstant.TOKEN_CACHE + user.getId(), 1000 * 5L, TimeUnit.MILLISECONDS); redisTemplate.expire(UserTokenConstant.TOKEN_CACHE + user.getId(), 1000 * 5L, TimeUnit.MILLISECONDS);
} }
@ApiOperation("踢用户下线")
@GetMapping("kickUser")
public void kickUser(String userId) {
redisTemplate.convertAndSend(UserTokenConstant.KICK_CHANNEL, userId);
}
} }

@ -1,16 +1,15 @@
package com.supervision.controller; package com.supervision.controller;
import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.websocket.OnClose; import javax.websocket.*;
import javax.websocket.OnError;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam; import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint; import javax.websocket.server.ServerEndpoint;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet; import java.security.Principal;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
@Component @Component
@ -22,14 +21,14 @@ public class WebSocketServer {
private static final AtomicInteger onlineNum = new AtomicInteger(0); private static final AtomicInteger onlineNum = new AtomicInteger(0);
//concurrent包的线程安全Set用来存放每个客户端对应的WebSocketServer对象。 //concurrent包的线程安全Set用来存放每个客户端对应的WebSocketServer对象。
private static final CopyOnWriteArraySet<Session> SESSION_POOL = new CopyOnWriteArraySet<Session>(); private static final ConcurrentHashMap<String, Session> SESSION_POOL = new ConcurrentHashMap<>();
/** /**
* *
*/ */
@OnOpen @OnOpen
public void onOpen(Session session, @PathParam(value = "uid") String uid) { public void onOpen(Session session, @PathParam(value = "uid") String uid) {
SESSION_POOL.add(session); SESSION_POOL.put(uid, session);
onlineNum.incrementAndGet(); onlineNum.incrementAndGet();
log.info(uid + "加入webSocket当前人数为" + onlineNum); log.info(uid + "加入webSocket当前人数为" + onlineNum);
} }
@ -38,8 +37,8 @@ public class WebSocketServer {
* *
*/ */
@OnClose @OnClose
public void onClose(Session session) { public void onClose(Session session, @PathParam(value = "uid") String uid) {
SESSION_POOL.remove(session); SESSION_POOL.remove(uid);
int cnt = onlineNum.decrementAndGet(); int cnt = onlineNum.decrementAndGet();
log.info("有连接关闭,当前连接数为:{}", cnt); log.info("有连接关闭,当前连接数为:{}", cnt);
} }
@ -59,7 +58,7 @@ public class WebSocketServer {
* *
*/ */
public void broadCastInfo(String message) throws IOException { public void broadCastInfo(String message) throws IOException {
for (Session session : SESSION_POOL) { for (Session session : SESSION_POOL.values()) {
if (session.isOpen()) { if (session.isOpen()) {
sendMessage(session, message); sendMessage(session, message);
} }
@ -76,7 +75,11 @@ public class WebSocketServer {
} }
// 实现一个方法用于踢下线用户 // 实现一个方法用于踢下线用户
public void kickUser(String userId) { public void kickUser(String userId) throws IOException {
SESSION_POOL.removeIf(session -> session.getUserPrincipal().getName().equals(userId)); log.info("踢用户{}下线", userId);
Session session = SESSION_POOL.get(userId);
if (ObjectUtil.isNotEmpty(session)) {
session.close(new CloseReason(CloseReason.CloseCodes.NORMAL_CLOSURE, "用户被踢下线"));
}
} }
} }

@ -8,6 +8,8 @@ import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener; import org.springframework.data.redis.connection.MessageListener;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.io.IOException;
@Slf4j @Slf4j
@Component @Component
@ -20,6 +22,10 @@ public class KickUserListener implements MessageListener {
public void onMessage(Message message, byte[] pattern) { public void onMessage(Message message, byte[] pattern) {
String userId = message.toString(); String userId = message.toString();
log.info("Redis的Channel:{}收到踢用户下线消息:{}", UserTokenConstant.KICK_CHANNEL, userId); log.info("Redis的Channel:{}收到踢用户下线消息:{}", UserTokenConstant.KICK_CHANNEL, userId);
webSocketServer.kickUser(userId); try {
webSocketServer.kickUser(userId);
} catch (IOException e) {
throw new RuntimeException(e);
}
} }
} }

Loading…
Cancel
Save