提交增加运维管理
This commit is contained in:
@@ -103,6 +103,11 @@
|
||||
<groupId>org.springframework.session</groupId>
|
||||
<artifactId>spring-session-data-redis</artifactId>
|
||||
</dependency>
|
||||
<!-- SpringBoot Websocket -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
|
||||
// .antMatchers("/oauth/css/**","/oauth/fonts/**","/oauth/js/**").permitAll()
|
||||
// dueros
|
||||
.antMatchers("/dueros").permitAll()
|
||||
|
||||
.antMatchers("/ws/alert/**").permitAll()
|
||||
// 除上面外的所有请求全部需要鉴权认证
|
||||
.anyRequest().authenticated()
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.xinda.framework.websocket;
|
||||
|
||||
import java.util.concurrent.Semaphore;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* 信号量相关处理
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class SemaphoreUtils
|
||||
{
|
||||
/**
|
||||
* SemaphoreUtils 日志控制器
|
||||
*/
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(SemaphoreUtils.class);
|
||||
|
||||
/**
|
||||
* 获取信号量
|
||||
*
|
||||
* @param semaphore
|
||||
* @return
|
||||
*/
|
||||
public static boolean tryAcquire(Semaphore semaphore)
|
||||
{
|
||||
boolean flag = false;
|
||||
|
||||
try
|
||||
{
|
||||
flag = semaphore.tryAcquire();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.error("获取信号量异常", e);
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* 释放信号量
|
||||
*
|
||||
* @param semaphore
|
||||
*/
|
||||
public static void release(Semaphore semaphore)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
semaphore.release();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.error("释放信号量异常", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
package com.xinda.framework.websocket;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.websocket.*;
|
||||
import javax.websocket.server.PathParam;
|
||||
import javax.websocket.server.ServerEndpoint;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@Component
|
||||
@ServerEndpoint("/ws/alert/{deptId}")
|
||||
public class WebSocketAlertServer {
|
||||
private static final Logger log = LoggerFactory.getLogger(WebSocketAlertServer.class);
|
||||
|
||||
//静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
|
||||
private static AtomicInteger onlineNum = new AtomicInteger();
|
||||
|
||||
//concurrent包的线程安全Set,用来存放每个客户端对应的WebSocketServer对象。
|
||||
private static ConcurrentHashMap<Long, Session> sessionPools = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* 线程安全list,用来存放 在线客户端账号
|
||||
*/
|
||||
public static List<Long> deptList = new CopyOnWriteArrayList<>();
|
||||
|
||||
|
||||
/**
|
||||
* 连接成功
|
||||
* @param session
|
||||
* @param deptId
|
||||
*/
|
||||
@OnOpen
|
||||
public void onOpen(Session session, @PathParam(value = "deptId") Long deptId) {
|
||||
sessionPools.put(deptId, session);
|
||||
if (!deptList.contains(deptId)) {
|
||||
addOnlineCount();
|
||||
deptList.add(deptId);
|
||||
}
|
||||
log.debug("ID为【" + deptId + "】的用户加入websocket!当前在线人数为:" + onlineNum);
|
||||
log.debug("当前在线:" + deptList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭连接
|
||||
* @param deptId
|
||||
*/
|
||||
@OnClose
|
||||
public void onClose(@PathParam(value = "deptId") Long deptId) {
|
||||
sessionPools.remove(deptId);
|
||||
if (deptList.contains(deptId)) {
|
||||
deptList.remove(deptId);
|
||||
subOnlineCount();
|
||||
}
|
||||
log.debug(deptId + "断开webSocket连接!当前人数为" + onlineNum);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息监听
|
||||
* @param message
|
||||
* @throws IOException
|
||||
*/
|
||||
@OnMessage
|
||||
public void onMessage(String message) throws IOException {
|
||||
String msg = message.replace("你", "我").replace("吗", "");
|
||||
// sendToUser(userId, JSONObject.toJSONString(jsonObject));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接错误
|
||||
* @param session
|
||||
* @param throwable
|
||||
* @throws IOException
|
||||
*/
|
||||
@OnError
|
||||
public void onError(Session session, Throwable throwable) throws IOException {
|
||||
log.error("websocket连接错误!");
|
||||
throwable.printStackTrace();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
*/
|
||||
public void sendMessage(Session session, String message) throws IOException, EncodeException {
|
||||
if (session != null) {
|
||||
synchronized (session) {
|
||||
session.getBasicRemote().sendText(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 给指定用户发送信息
|
||||
*/
|
||||
public void sendToUser(Long deptId, String message) {
|
||||
Session session = sessionPools.get(deptId);
|
||||
try {
|
||||
if (session != null) {
|
||||
sendMessage(session, message);
|
||||
}else {
|
||||
log.debug("推送用户不在线");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void addOnlineCount() {
|
||||
onlineNum.incrementAndGet();
|
||||
}
|
||||
|
||||
public static void subOnlineCount() {
|
||||
onlineNum.decrementAndGet();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.xinda.framework.websocket;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
|
||||
|
||||
/**
|
||||
* websocket 配置
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Configuration
|
||||
public class WebSocketConfig
|
||||
{
|
||||
@Bean
|
||||
public ServerEndpointExporter serverEndpointExporter()
|
||||
{
|
||||
return new ServerEndpointExporter();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
package com.xinda.framework.websocket;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import javax.websocket.Session;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* websocket 客户端用户集
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class WebSocketUsers
|
||||
{
|
||||
/**
|
||||
* WebSocketUsers 日志控制器
|
||||
*/
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketUsers.class);
|
||||
|
||||
/**
|
||||
* 用户集
|
||||
*/
|
||||
private static Map<String, Session> USERS = new ConcurrentHashMap<String, Session>();
|
||||
|
||||
/**
|
||||
* 存储用户
|
||||
*
|
||||
* @param key 唯一键
|
||||
* @param session 用户信息
|
||||
*/
|
||||
public static void put(String key, Session session)
|
||||
{
|
||||
USERS.put(key, session);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除用户
|
||||
*
|
||||
* @param session 用户信息
|
||||
*
|
||||
* @return 移除结果
|
||||
*/
|
||||
public static boolean remove(Session session)
|
||||
{
|
||||
String key = null;
|
||||
boolean flag = USERS.containsValue(session);
|
||||
if (flag)
|
||||
{
|
||||
Set<Map.Entry<String, Session>> entries = USERS.entrySet();
|
||||
for (Map.Entry<String, Session> entry : entries)
|
||||
{
|
||||
Session value = entry.getValue();
|
||||
if (value.equals(session))
|
||||
{
|
||||
key = entry.getKey();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return remove(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移出用户
|
||||
*
|
||||
* @param key 键
|
||||
*/
|
||||
public static boolean remove(String key)
|
||||
{
|
||||
LOGGER.info("\n 正在移出用户 - {}", key);
|
||||
Session remove = USERS.remove(key);
|
||||
if (remove != null)
|
||||
{
|
||||
boolean containsValue = USERS.containsValue(remove);
|
||||
LOGGER.info("\n 移出结果 - {}", containsValue ? "失败" : "成功");
|
||||
return containsValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取在线用户列表
|
||||
*
|
||||
* @return 返回用户集合
|
||||
*/
|
||||
public static Map<String, Session> getUsers()
|
||||
{
|
||||
return USERS;
|
||||
}
|
||||
|
||||
/**
|
||||
* 群发消息文本消息
|
||||
*
|
||||
* @param message 消息内容
|
||||
*/
|
||||
public static void sendMessageToUsersByText(String message)
|
||||
{
|
||||
Collection<Session> values = USERS.values();
|
||||
for (Session value : values)
|
||||
{
|
||||
sendMessageToUserByText(value, message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送文本消息
|
||||
*
|
||||
* @param session 自己的用户名
|
||||
* @param message 消息内容
|
||||
*/
|
||||
public static void sendMessageToUserByText(Session session, String message)
|
||||
{
|
||||
if (session != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
session.getBasicRemote().sendText(message);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
LOGGER.error("\n[发送消息异常]", e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGGER.info("\n[你已离线]");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user