mirror of
https://github.com/continew-org/continew-starter.git
synced 2025-09-08 16:57:09 +08:00
feat(messaging/websocket): 新增消息模块 - WebSocket
This commit is contained in:
@@ -114,6 +114,16 @@ public class PropertiesConstants {
|
||||
*/
|
||||
public static final String CAPTCHA_BEHAVIOR = CAPTCHA + StringConstants.DOT + "behavior";
|
||||
|
||||
/**
|
||||
* 消息配置
|
||||
*/
|
||||
public static final String MESSAGING = CONTINEW_STARTER + StringConstants.DOT + "messaging";
|
||||
|
||||
/**
|
||||
* WebSocket 配置
|
||||
*/
|
||||
public static final String MESSAGING_WEBSOCKET = MESSAGING + StringConstants.DOT + "websocket";
|
||||
|
||||
private PropertiesConstants() {
|
||||
}
|
||||
}
|
||||
|
@@ -389,6 +389,13 @@
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 消息模块 - WebSocket -->
|
||||
<dependency>
|
||||
<groupId>top.continew</groupId>
|
||||
<artifactId>continew-starter-messaging-websocket</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 消息模块 - 邮件 -->
|
||||
<dependency>
|
||||
<groupId>top.continew</groupId>
|
||||
|
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>top.continew</groupId>
|
||||
<artifactId>continew-starter-messaging</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>continew-starter-messaging-websocket</artifactId>
|
||||
<description>ContiNew Starter 消息模块 - WebSocket</description>
|
||||
|
||||
<dependencies>
|
||||
<!-- WebSocket 支持 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.starter.messaging.websocket.autoconfigure;
|
||||
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
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.server.HandshakeInterceptor;
|
||||
import top.continew.starter.core.constant.PropertiesConstants;
|
||||
import top.continew.starter.messaging.websocket.core.CurrentUserProvider;
|
||||
import top.continew.starter.messaging.websocket.core.WebSocketInterceptor;
|
||||
import top.continew.starter.messaging.websocket.dao.WebSocketSessionDao;
|
||||
import top.continew.starter.messaging.websocket.dao.WebSocketSessionDaoDefaultImpl;
|
||||
|
||||
/**
|
||||
* WebSocket 自动配置
|
||||
*
|
||||
* @author WeiRan
|
||||
* @author Charles7c
|
||||
* @since 2.1.0
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@EnableWebSocket
|
||||
@EnableConfigurationProperties(WebSocketProperties.class)
|
||||
@ConditionalOnProperty(prefix = PropertiesConstants.MESSAGING_WEBSOCKET, name = PropertiesConstants.ENABLED, havingValue = "true")
|
||||
public class WebSocketAutoConfiguration {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(WebSocketAutoConfiguration.class);
|
||||
private final WebSocketProperties properties;
|
||||
|
||||
public WebSocketAutoConfiguration(WebSocketProperties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public WebSocketConfigurer webSocketConfigurer(WebSocketHandler handler, HandshakeInterceptor interceptor) {
|
||||
return registry -> registry.addHandler(handler, properties.getPath())
|
||||
.addInterceptors(interceptor)
|
||||
.setAllowedOrigins(properties.getAllowedOrigins().toArray(String[]::new));
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public WebSocketHandler webSocketHandler() {
|
||||
return new top.continew.starter.messaging.websocket.core.WebSocketHandler(properties, SpringUtil
|
||||
.getBean(WebSocketSessionDao.class));
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public HandshakeInterceptor handshakeInterceptor() {
|
||||
return new WebSocketInterceptor(properties, SpringUtil.getBean(CurrentUserProvider.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* WebSocket 会话 DAO
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public WebSocketSessionDao webSocketSessionDao() {
|
||||
return new WebSocketSessionDaoDefaultImpl();
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前用户 Provider(如不提供,则报错)
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public CurrentUserProvider currentUserProvider() {
|
||||
throw new NoSuchBeanDefinitionException(CurrentUserProvider.class);
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void postConstruct() {
|
||||
log.debug("[ContiNew Starter] - Auto Configuration 'Messaging-WebSocket' completed initialization.");
|
||||
}
|
||||
}
|
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.starter.messaging.websocket.autoconfigure;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import top.continew.starter.core.constant.PropertiesConstants;
|
||||
import top.continew.starter.core.constant.StringConstants;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* WebSocket 配置属性
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2.1.0
|
||||
*/
|
||||
@ConfigurationProperties(PropertiesConstants.MESSAGING_WEBSOCKET)
|
||||
public class WebSocketProperties {
|
||||
|
||||
private static final List<String> ALL = Collections.singletonList(StringConstants.ASTERISK);
|
||||
|
||||
/**
|
||||
* 是否启用 WebSocket
|
||||
*/
|
||||
private boolean enabled = false;
|
||||
|
||||
/**
|
||||
* 路径
|
||||
*/
|
||||
private String path = StringConstants.SLASH + "websocket";
|
||||
|
||||
/**
|
||||
* 允许跨域的域名
|
||||
*/
|
||||
private List<String> allowedOrigins = new ArrayList<>(ALL);
|
||||
|
||||
/**
|
||||
* 当前登录用户 Key
|
||||
*/
|
||||
private String currentUserKey = "CURRENT_USER";
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public List<String> getAllowedOrigins() {
|
||||
return allowedOrigins;
|
||||
}
|
||||
|
||||
public void setAllowedOrigins(List<String> allowedOrigins) {
|
||||
this.allowedOrigins = allowedOrigins;
|
||||
}
|
||||
|
||||
public String getCurrentUserKey() {
|
||||
return currentUserKey;
|
||||
}
|
||||
|
||||
public void setCurrentUserKey(String currentUserKey) {
|
||||
this.currentUserKey = currentUserKey;
|
||||
}
|
||||
}
|
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.starter.messaging.websocket.core;
|
||||
|
||||
import org.springframework.http.server.ServletServerHttpRequest;
|
||||
import top.continew.starter.messaging.websocket.model.CurrentUser;
|
||||
|
||||
/**
|
||||
* 当前登录用户 Provider
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public interface CurrentUserProvider {
|
||||
|
||||
/**
|
||||
* 获取当前登录用户
|
||||
*
|
||||
* @param request 请求对象
|
||||
* @return 当前登录用户
|
||||
*/
|
||||
CurrentUser getCurrentUser(ServletServerHttpRequest request);
|
||||
}
|
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.starter.messaging.websocket.core;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
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.AbstractWebSocketHandler;
|
||||
import top.continew.starter.messaging.websocket.autoconfigure.WebSocketProperties;
|
||||
import top.continew.starter.messaging.websocket.dao.WebSocketSessionDao;
|
||||
|
||||
/**
|
||||
* WebSocket 处理器
|
||||
*
|
||||
* @author WeiRan
|
||||
* @author Charles7c
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public class WebSocketHandler extends AbstractWebSocketHandler {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(WebSocketHandler.class);
|
||||
private final WebSocketProperties webSocketProperties;
|
||||
private final WebSocketSessionDao webSocketSessionDao;
|
||||
|
||||
public WebSocketHandler(WebSocketProperties webSocketProperties, WebSocketSessionDao webSocketSessionDao) {
|
||||
this.webSocketProperties = webSocketProperties;
|
||||
this.webSocketSessionDao = webSocketSessionDao;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
|
||||
log.info("WebSocket receive message. sessionId: {}, message: {}.", session.getId(), message.getPayload());
|
||||
super.handleTextMessage(session, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterConnectionEstablished(WebSocketSession session) {
|
||||
String sessionKey = Convert.toStr(session.getAttributes().get(webSocketProperties.getCurrentUserKey()));
|
||||
webSocketSessionDao.add(sessionKey, session);
|
||||
log.info("WebSocket connect successfully. sessionKey: {}.", sessionKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
|
||||
String sessionKey = Convert.toStr(session.getAttributes().get(webSocketProperties.getCurrentUserKey()));
|
||||
webSocketSessionDao.delete(sessionKey);
|
||||
log.info("WebSocket connect closed. sessionKey: {}.", sessionKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTransportError(WebSocketSession session, Throwable exception) {
|
||||
log.error("WebSocket transport error. sessionId: {}.", session.getId(), exception);
|
||||
}
|
||||
}
|
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.starter.messaging.websocket.core;
|
||||
|
||||
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.support.HttpSessionHandshakeInterceptor;
|
||||
import top.continew.starter.messaging.websocket.autoconfigure.WebSocketProperties;
|
||||
import top.continew.starter.messaging.websocket.model.CurrentUser;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* WebSocket 拦截器
|
||||
*
|
||||
* @author WeiRan
|
||||
* @author Charles7c
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public class WebSocketInterceptor extends HttpSessionHandshakeInterceptor {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(WebSocketInterceptor.class);
|
||||
private final WebSocketProperties webSocketProperties;
|
||||
private final CurrentUserProvider currentUserProvider;
|
||||
|
||||
public WebSocketInterceptor(WebSocketProperties webSocketProperties, CurrentUserProvider currentUserProvider) {
|
||||
this.webSocketProperties = webSocketProperties;
|
||||
this.currentUserProvider = currentUserProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean beforeHandshake(ServerHttpRequest request,
|
||||
ServerHttpResponse response,
|
||||
WebSocketHandler wsHandler,
|
||||
Map<String, Object> attributes) {
|
||||
CurrentUser currentUser = currentUserProvider.getCurrentUser((ServletServerHttpRequest)request);
|
||||
attributes.put(webSocketProperties.getCurrentUserKey(), currentUser.getUserId());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterHandshake(ServerHttpRequest request,
|
||||
ServerHttpResponse response,
|
||||
WebSocketHandler wsHandler,
|
||||
Exception exception) {
|
||||
super.afterHandshake(request, response, wsHandler, exception);
|
||||
}
|
||||
}
|
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.starter.messaging.websocket.dao;
|
||||
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
/**
|
||||
* WebSocket 会话 DAO
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public interface WebSocketSessionDao {
|
||||
|
||||
/**
|
||||
* 添加会话
|
||||
*
|
||||
* @param key 会话 Key
|
||||
* @param session 会话信息
|
||||
*/
|
||||
void add(String key, WebSocketSession session);
|
||||
|
||||
/**
|
||||
* 删除会话
|
||||
*
|
||||
* @param key 会话 Key
|
||||
*/
|
||||
void delete(String key);
|
||||
|
||||
/**
|
||||
* 获取会话
|
||||
*
|
||||
* @param key 会话 Key
|
||||
* @return 会话信息
|
||||
*/
|
||||
WebSocketSession get(String key);
|
||||
}
|
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.starter.messaging.websocket.dao;
|
||||
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* WebSocket 会话 DAO 默认实现
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public class WebSocketSessionDaoDefaultImpl implements WebSocketSessionDao {
|
||||
|
||||
private static final Map<String, WebSocketSession> SESSION_MAP = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public void add(String key, WebSocketSession session) {
|
||||
SESSION_MAP.put(key, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete(String key) {
|
||||
SESSION_MAP.remove(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebSocketSession get(String key) {
|
||||
return SESSION_MAP.get(key);
|
||||
}
|
||||
}
|
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.starter.messaging.websocket.model;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 当前登录用户信息
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public class CurrentUser implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 用户 ID
|
||||
*/
|
||||
private String userId;
|
||||
|
||||
/**
|
||||
* 扩展字段
|
||||
*/
|
||||
private Object extend;
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public Object getExtend() {
|
||||
return extend;
|
||||
}
|
||||
|
||||
public void setExtend(Object extend) {
|
||||
this.extend = extend;
|
||||
}
|
||||
}
|
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.starter.messaging.websocket.util;
|
||||
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.socket.TextMessage;
|
||||
import org.springframework.web.socket.WebSocketMessage;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
import top.continew.starter.messaging.websocket.dao.WebSocketSessionDao;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* WebSocket 工具类
|
||||
*
|
||||
* @author WeiRan
|
||||
* @author Charles7c
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public class WebSocketUtils {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(WebSocketUtils.class);
|
||||
private static final WebSocketSessionDao SESSION_DAO = SpringUtil.getBean(WebSocketSessionDao.class);
|
||||
|
||||
private WebSocketUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
*
|
||||
* @param sessionKey 会话 Key
|
||||
* @param message 消息内容
|
||||
*/
|
||||
public static void sendMessage(String sessionKey, String message) {
|
||||
WebSocketSession session = SESSION_DAO.get(sessionKey);
|
||||
sendMessage(session, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
*
|
||||
* @param session 会话
|
||||
* @param message 消息内容
|
||||
*/
|
||||
public static void sendMessage(WebSocketSession session, String message) {
|
||||
sendMessage(session, new TextMessage(message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
*
|
||||
* @param session 会话
|
||||
* @param message 消息内容
|
||||
*/
|
||||
public static void sendMessage(WebSocketSession session, WebSocketMessage<?> message) {
|
||||
if (session == null || !session.isOpen()) {
|
||||
log.warn("WebSocket session closed.");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
session.sendMessage(message);
|
||||
} catch (IOException e) {
|
||||
log.error("WebSocket send message failed. sessionId: {}.", session.getId(), e);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1 @@
|
||||
top.continew.starter.messaging.websocket.autoconfigure.WebSocketAutoConfiguration
|
@@ -15,6 +15,7 @@
|
||||
|
||||
<modules>
|
||||
<module>continew-starter-messaging-mail</module>
|
||||
<module>continew-starter-messaging-websocket</module>
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
|
@@ -30,13 +30,6 @@
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-undertow</artifactId>
|
||||
<!-- 移除 websocket 依赖,后续使用 websocket 可考虑由 Netty 提供。另可解决日志警告:UT026010: Buffer pool was not set on WebSocketDeploymentInfo, the default pool will be used -->
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>io.undertow</groupId>
|
||||
<artifactId>undertow-websockets-jsr</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- Hibernate Validator -->
|
||||
|
@@ -33,6 +33,8 @@ import java.util.List;
|
||||
@ConfigurationProperties(PropertiesConstants.CORS)
|
||||
public class CorsProperties {
|
||||
|
||||
private static final List<String> ALL = Collections.singletonList(StringConstants.ASTERISK);
|
||||
|
||||
/**
|
||||
* 是否启用跨域配置
|
||||
*/
|
||||
@@ -58,8 +60,6 @@ public class CorsProperties {
|
||||
*/
|
||||
private List<String> exposedHeaders = new ArrayList<>();
|
||||
|
||||
private static final List<String> ALL = Collections.singletonList(StringConstants.ASTERISK);
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
Reference in New Issue
Block a user