【8.1.0】【socket】移除socket模块

pull/60/head
fengshuonan 2024-01-11 20:14:14 +08:00
parent 6d731c8647
commit 14bd16efad
28 changed files with 0 additions and 1298 deletions

View File

@ -1,36 +0,0 @@
<?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>cn.stylefeng.roses</groupId>
<artifactId>roses-kernel</artifactId>
<version>8.1.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>kernel-d-socket</artifactId>
<packaging>pom</packaging>
<modules>
<module>socket-api</module>
<module>socket-business-websocket</module>
<module>socket-spring-boot-starter</module>
</modules>
<dependencies>
<!-- 开发规则 -->
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>kernel-a-rule</artifactId>
<version>${roses.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -1 +0,0 @@
socket模块的api

View File

@ -1,41 +0,0 @@
<?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>cn.stylefeng.roses</groupId>
<artifactId>kernel-d-socket</artifactId>
<version>8.1.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>socket-api</artifactId>
<packaging>jar</packaging>
<dependencies>
<!--config模块的api-->
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>config-api</artifactId>
<version>${roses.version}</version>
</dependency>
<!-- Getty核心包 -->
<dependency>
<groupId>com.gettyio</groupId>
<artifactId>getty-core</artifactId>
</dependency>
<!-- 拓展包 -->
<dependency>
<groupId>com.gettyio</groupId>
<artifactId>getty-expansion</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -1,70 +0,0 @@
package cn.stylefeng.roses.kernel.socket.api;
import cn.stylefeng.roses.kernel.socket.api.exception.SocketException;
import cn.stylefeng.roses.kernel.socket.api.message.SocketMsgCallbackInterface;
/**
* Socket
* <p>
* SocketAPI
*
* @author majianguo
* @since 2021/6/2 9:25
*/
public interface SocketOperatorApi {
/**
*
*
* @param msgType {@link cn.stylefeng.roses.kernel.socket.api.enums}
* @param sessionId ID
* @param msg
* @author majianguo
* @since 2021/6/11 2:19
**/
void sendMsgOfUserSessionBySessionId(String msgType, String sessionId, Object msg) throws SocketException;
/**
*
* <p>
*
*
* @param msgType {@link cn.stylefeng.roses.kernel.socket.api.enums}
* @param userId ID
* @param msg
* @author majianguo
* @since 2021/6/2 9:35
**/
void sendMsgOfUserSession(String msgType, String userId, Object msg) throws SocketException;
/**
*
*
* @param msgType {@link cn.stylefeng.roses.kernel.socket.api.enums}
* @param msg
* @author majianguo
* @since 2021/6/2 9:35
**/
void sendMsgOfAllUserSession(String msgType, Object msg);
/**
* id
*
* @param socketId id
* @author majianguo
* @since 2021/8/13 16:00
**/
void closeSocketBySocketId(String socketId);
/**
*
* <p>
* 1.,
*
* @param msgType {@link cn.stylefeng.roses.kernel.socket.api.enums}
* @param callbackInterface
* @author majianguo
* @since 2021/6/2 9:54
**/
void msgTypeCallback(String msgType, SocketMsgCallbackInterface callbackInterface);
}

View File

@ -1,45 +0,0 @@
/*
* Copyright [2020-2030] [https://www.stylefeng.cn]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*
* GunsAPACHE LICENSE 2.0使
*
* 1.LICENSE
* 2.Guns
* 3.
* 4. https://gitee.com/stylefeng/guns
* 5. https://gitee.com/stylefeng/guns
* 6.
*/
package cn.stylefeng.roses.kernel.socket.api.constants;
/**
* socket
*
* @author majianguo
* @since 2021/6/1 11:21
*/
public interface SocketConstants {
/**
* socket
*/
String SOCKET_MODULE_NAME = "kernel-d-socket";
/**
*
*/
String SOCKET_EXCEPTION_STEP_CODE = "30";
}

View File

@ -1,34 +0,0 @@
package cn.stylefeng.roses.kernel.socket.api.enums;
import lombok.Getter;
/**
*
* <p>
* 使
*
* @author majianguo
* @since 2021/6/3 9:14
*/
@Getter
public enum ClientMessageTypeEnum {
/**
*
*/
USER_CONNECTION_AUTHENTICATION("200000", "用户连接鉴权"),
/**
*
*/
USER_HEART("299999", "用户心跳消息类型");
private final String code;
private final String name;
ClientMessageTypeEnum(String code, String name) {
this.code = code;
this.name = name;
}
}

View File

@ -1,34 +0,0 @@
package cn.stylefeng.roses.kernel.socket.api.enums;
import lombok.Getter;
/**
*
* <p>
* 使
*
* @author majianguo
* @since 2021/6/3 9:14
*/
@Getter
public enum ServerMessageTypeEnum {
/**
*
*/
SYS_NOTICE_MSG_TYPE("100001", "系统通知消息类型"),
/**
*
*/
SYS_REPLY_MSG_TYPE("100002", "连接消息回复");
private final String code;
private final String name;
ServerMessageTypeEnum(String code, String name) {
this.code = code;
this.name = name;
}
}

View File

@ -1,39 +0,0 @@
package cn.stylefeng.roses.kernel.socket.api.enums;
import lombok.Getter;
/**
*
* <p>
*
*
* @author majianguo
* @since 2021/6/3 9:14
*/
@Getter
public enum SystemMessageTypeEnum {
/**
*
*/
SYS_LISTENER_ONOPEN("S00001", "监听首次连接"),
/**
*
*/
SYS_LISTENER_ONCLOSE("S00002", "监听断开连接"),
/**
*
*/
SYS_LISTENER_ONERROR("S00003", "监听异常信息");
private final String code;
private final String name;
SystemMessageTypeEnum(String code, String name) {
this.code = code;
this.name = name;
}
}

View File

@ -1,47 +0,0 @@
/*
* Copyright [2020-2030] [https://www.stylefeng.cn]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*
* GunsAPACHE LICENSE 2.0使
*
* 1.LICENSE
* 2.Guns
* 3.
* 4. https://gitee.com/stylefeng/guns
* 5. https://gitee.com/stylefeng/guns
* 6.
*/
package cn.stylefeng.roses.kernel.socket.api.exception;
import cn.stylefeng.roses.kernel.rule.exception.AbstractExceptionEnum;
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
import cn.stylefeng.roses.kernel.socket.api.constants.SocketConstants;
/**
* Socket
*
* @author majianguo
* @since 2021/6/1 11:23
*/
public class SocketException extends ServiceException {
public SocketException(AbstractExceptionEnum exception) {
super(SocketConstants.SOCKET_MODULE_NAME, exception);
}
public SocketException(String errorCode, String userTip) {
super(SocketConstants.SOCKET_MODULE_NAME, errorCode, userTip);
}
}

View File

@ -1,66 +0,0 @@
/*
* Copyright [2020-2030] [https://www.stylefeng.cn]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*
* GunsAPACHE LICENSE 2.0使
*
* 1.LICENSE
* 2.Guns
* 3.
* 4. https://gitee.com/stylefeng/guns
* 5. https://gitee.com/stylefeng/guns
* 6.
*/
package cn.stylefeng.roses.kernel.socket.api.exception.enums;
import cn.stylefeng.roses.kernel.rule.constants.RuleConstants;
import cn.stylefeng.roses.kernel.rule.exception.AbstractExceptionEnum;
import cn.stylefeng.roses.kernel.socket.api.constants.SocketConstants;
import lombok.Getter;
/**
* Socket
*
* @author majianguo
* @since 2021/6/1 11:25
*/
@Getter
public enum SocketExceptionEnum implements AbstractExceptionEnum {
/**
* Socket
*/
SOCKET_ERROR(RuleConstants.THIRD_ERROR_TYPE_CODE + SocketConstants.SOCKET_EXCEPTION_STEP_CODE + "01", "操作异常,具体信息为:{}"),
/**
*
*/
SESSION_NOT_EXIST(RuleConstants.THIRD_ERROR_TYPE_CODE + SocketConstants.SOCKET_EXCEPTION_STEP_CODE + "02", "会话不存在");
/**
*
*/
private final String errorCode;
/**
*
*/
private final String userTip;
SocketExceptionEnum(String errorCode, String userTip) {
this.errorCode = errorCode;
this.userTip = userTip;
}
}

View File

@ -1,24 +0,0 @@
package cn.stylefeng.roses.kernel.socket.api.message;
import cn.stylefeng.roses.kernel.socket.api.session.pojo.SocketSession;
/**
* Socket
*
* @author majianguo
* @since 2021/6/2 9:53
*/
@FunctionalInterface
public interface SocketMsgCallbackInterface {
/**
*
*
* @param msgType
* @param msg
* @param socketSession
* @author majianguo
* @since 2021/6/2 9:51
**/
void callback(String msgType, Object msg, SocketSession socketSession);
}

View File

@ -1,70 +0,0 @@
/*
* Copyright [2020-2030] [https://www.stylefeng.cn]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*
* GunsAPACHE LICENSE 2.0使
*
* 1.LICENSE
* 2.Guns
* 3.
* 4. https://gitee.com/stylefeng/guns
* 5. https://gitee.com/stylefeng/guns
* 6.
*/
package cn.stylefeng.roses.kernel.socket.api.session;
/**
* socket
* <p>
*
* WebSocket{@link cn.stylefeng.roses.kernel.socket.websocket.operator.channel}
*
* @author majianguo
* @since 2021/6/1 11:46
*/
public interface SocketSessionOperatorApi {
/**
*
*
* @author majianguo
* @since 2021/6/1 11:48
**/
void writeAndFlush(Object obj);
/**
*
*
* @author majianguo
* @since 2021/6/1 11:48
**/
void writeToChannel(Object obj);
/**
*
*
* @author majianguo
* @since 2021/6/1 11:48
**/
void close();
/**
*
*
* @return {@link boolean}
* @author majianguo
* @since 2021/6/1 11:50
**/
boolean isInvalid();
}

View File

@ -1,55 +0,0 @@
package cn.stylefeng.roses.kernel.socket.api.session.pojo;
import cn.stylefeng.roses.kernel.socket.api.session.SocketSessionOperatorApi;
import lombok.Data;
/**
* Socket
*
* @author majianguo
* @since 2021/6/1 11:28
*/
@Data
public class SocketSession<T extends SocketSessionOperatorApi> {
/**
* ID(使ID)
*/
private String sessionId;
/**
*
*/
private String userId;
/**
*
*/
private String messageType;
/**
* token
*/
private String token;
/**
*
*/
private Long connectionTime;
/**
*
*/
private Long lastActiveTime;
/**
* API
*/
private T socketOperatorApi;
/**
*
*/
private Object data;
}

View File

@ -1,45 +0,0 @@
<?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>cn.stylefeng.roses</groupId>
<artifactId>kernel-d-socket</artifactId>
<version>8.1.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>socket-business-websocket</artifactId>
<dependencies>
<!--Spring boot WebSocket实现-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!--web模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--socket模块api-->
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>socket-api</artifactId>
<version>${roses.version}</version>
</dependency>
<!--jwt模块的sdk-->
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>auth-api</artifactId>
<version>${roses.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -1,20 +0,0 @@
package cn.stylefeng.roses.kernel.socket.business.websocket.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* WebSocket
*
* @author majianguo
* @since 2021/6/21 5:01
*/
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}

View File

@ -1,46 +0,0 @@
package cn.stylefeng.roses.kernel.socket.business.websocket.message;
import cn.stylefeng.roses.kernel.socket.api.message.SocketMsgCallbackInterface;
import java.util.HashMap;
import java.util.Map;
/**
*
* <p>
*
*
* @author majianguo
* @since 2021/6/1 2:20
*/
public class SocketMessageCenter {
/**
*
*/
private static final Map<String, SocketMsgCallbackInterface> MESSAGE_LISTENER_MAP = new HashMap<>();
/**
*
*
* @param msgType
* @param listener
* @author majianguo
* @since 2021/6/1 2:25
**/
public static void setMessageListener(String msgType, SocketMsgCallbackInterface listener) {
MESSAGE_LISTENER_MAP.put(msgType, listener);
}
/**
*
*
* @param msgType
* @return {@link SocketMsgCallbackInterface}
* @author majianguo
* @since 2021/6/1 2:26
**/
public static SocketMsgCallbackInterface getSocketMsgCallbackInterface(String msgType) {
return MESSAGE_LISTENER_MAP.get(msgType);
}
}

View File

@ -1,80 +0,0 @@
package cn.stylefeng.roses.kernel.socket.business.websocket.operator;
import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.roses.kernel.socket.api.SocketOperatorApi;
import cn.stylefeng.roses.kernel.socket.api.exception.SocketException;
import cn.stylefeng.roses.kernel.socket.api.exception.enums.SocketExceptionEnum;
import cn.stylefeng.roses.kernel.socket.api.message.SocketMsgCallbackInterface;
import cn.stylefeng.roses.kernel.socket.api.session.pojo.SocketSession;
import cn.stylefeng.roses.kernel.socket.business.websocket.message.SocketMessageCenter;
import cn.stylefeng.roses.kernel.socket.business.websocket.pojo.WebSocketMessageDTO;
import cn.stylefeng.roses.kernel.socket.business.websocket.session.SessionCenter;
import cn.stylefeng.roses.kernel.socket.business.websocket.operator.channel.GunsSocketOperator;
import java.util.Collection;
import java.util.List;
/**
* WebSocket
* <p>
* Spring bootSocketOperatorApisocketSpring
*
* @author majianguo
* @since 2021/6/2 10:41
*/
public class WebSocketOperator implements SocketOperatorApi {
@Override
public void sendMsgOfUserSessionBySessionId(String msgType, String sessionId, Object msg) throws SocketException {
SocketSession<GunsSocketOperator> session = SessionCenter.getSessionBySessionId(sessionId);
if (ObjectUtil.isEmpty(session)) {
throw new SocketException(SocketExceptionEnum.SESSION_NOT_EXIST);
}
WebSocketMessageDTO webSocketMessageDTO = new WebSocketMessageDTO();
webSocketMessageDTO.setData(msg);
webSocketMessageDTO.setServerMsgType(msgType);
session.getSocketOperatorApi().writeAndFlush(webSocketMessageDTO);
}
@Override
public void sendMsgOfUserSession(String msgType, String userId, Object msg) throws SocketException {
// 根据用户ID获取会话
List<SocketSession<GunsSocketOperator>> socketSessionList = SessionCenter.getSessionByUserIdAndMsgType(userId);
if (ObjectUtil.isEmpty(socketSessionList)) {
throw new SocketException(SocketExceptionEnum.SESSION_NOT_EXIST);
}
WebSocketMessageDTO webSocketMessageDTO = new WebSocketMessageDTO();
webSocketMessageDTO.setData(msg);
webSocketMessageDTO.setServerMsgType(msgType);
for (SocketSession<GunsSocketOperator> session : socketSessionList) {
// 发送内容
session.getSocketOperatorApi().writeAndFlush(webSocketMessageDTO);
}
}
@Override
public void sendMsgOfAllUserSession(String msgType, Object msg) {
Collection<List<SocketSession<GunsSocketOperator>>> values = SessionCenter.getSocketSessionMap().values();
WebSocketMessageDTO webSocketMessageDTO = new WebSocketMessageDTO();
webSocketMessageDTO.setData(msg);
webSocketMessageDTO.setServerMsgType(msgType);
for (List<SocketSession<GunsSocketOperator>> sessions : values) {
for (SocketSession<GunsSocketOperator> session : sessions) {
// 找到该类型的通道
if (session.getMessageType().equals(msgType)) {
session.getSocketOperatorApi().writeAndFlush(webSocketMessageDTO);
}
}
}
}
@Override
public void closeSocketBySocketId(String socketId) {
SessionCenter.closed(socketId);
}
@Override
public void msgTypeCallback(String msgType, SocketMsgCallbackInterface callbackInterface) {
SocketMessageCenter.setMessageListener(msgType, callbackInterface);
}
}

View File

@ -1,59 +0,0 @@
package cn.stylefeng.roses.kernel.socket.business.websocket.operator.channel;
import com.alibaba.fastjson.JSON;
import javax.websocket.Session;
import java.io.IOException;
/**
* Socket
* <p>
* Spring BootWebSocket
*
* @author majianguo
* @since 2021/6/1 3:41
*/
public class GunsSocketOperator implements SocketChannelExpandInterFace {
/**
*
*/
private Session socketChannel;
public GunsSocketOperator(Session socketChannel) {
this.socketChannel = socketChannel;
}
@Override
public void writeAndFlush(Object obj) {
try {
if (socketChannel.isOpen()) {
socketChannel.getBasicRemote().sendText(JSON.toJSONString(obj));
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void writeToChannel(Object obj) {
if (socketChannel.isOpen()) {
socketChannel.getAsyncRemote().sendText(JSON.toJSONString(obj));
}
}
@Override
public void close() {
try {
if (socketChannel.isOpen()) {
socketChannel.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public boolean isInvalid() {
return socketChannel.isOpen();
}
}

View File

@ -1,15 +0,0 @@
package cn.stylefeng.roses.kernel.socket.business.websocket.operator.channel;
import cn.stylefeng.roses.kernel.socket.api.session.SocketSessionOperatorApi;
/**
* Api
* <p>
* SocketOperatorApi
*
* @author majianguo
* @since 2021/6/1 3:44
*/
public interface SocketChannelExpandInterFace extends SocketSessionOperatorApi {
}

View File

@ -1,48 +0,0 @@
package cn.stylefeng.roses.kernel.socket.business.websocket.pojo;
import cn.stylefeng.roses.kernel.socket.api.SocketOperatorApi;
import lombok.Data;
/**
* WebSocket
* <p>
* serverMsgTypeclientMsgType
* 1.serverMsgType
* (type:100001),
* <p>
* 2.clientMsgType
* (type:299999)
* {@link SocketOperatorApi#msgTypeCallback}
*
* @author majianguo
* @since 2021/6/1 2:56
*/
@Data
public class WebSocketMessageDTO {
/**
* ()
*/
private String serverMsgType;
/**
* ()
*/
private String clientMsgType;
/**
* Id
*/
private String toUserId;
/**
* ID
*/
private String formUserId;
/**
*
*/
private Object data;
}

View File

@ -1,182 +0,0 @@
package cn.stylefeng.roses.kernel.socket.business.websocket.server;
import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.roses.kernel.auth.api.context.AuthJwtContext;
import cn.stylefeng.roses.kernel.auth.api.pojo.payload.DefaultJwtPayload;
import cn.stylefeng.roses.kernel.socket.api.enums.ClientMessageTypeEnum;
import cn.stylefeng.roses.kernel.socket.api.enums.ServerMessageTypeEnum;
import cn.stylefeng.roses.kernel.socket.api.enums.SystemMessageTypeEnum;
import cn.stylefeng.roses.kernel.socket.api.message.SocketMsgCallbackInterface;
import cn.stylefeng.roses.kernel.socket.api.session.pojo.SocketSession;
import cn.stylefeng.roses.kernel.socket.business.websocket.message.SocketMessageCenter;
import cn.stylefeng.roses.kernel.socket.business.websocket.operator.channel.GunsSocketOperator;
import cn.stylefeng.roses.kernel.socket.business.websocket.pojo.WebSocketMessageDTO;
import cn.stylefeng.roses.kernel.socket.business.websocket.session.SessionCenter;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
/**
*
*
* @author majianguo
* @since 2021/6/1 2:35
*/
@Slf4j
@ServerEndpoint(value = "/webSocket/{token}")
@Component
public class WebSocketServer {
/**
*
* <p>
*
*
* @param session
* @author majianguo
* @since 2021/6/21 5:14
**/
@OnOpen
public void onOpen(Session session, @PathParam("token") String token) {
String userId = null;
try {
// 解析用户信息
DefaultJwtPayload defaultPayload = AuthJwtContext.me().getDefaultPayload(token);
userId = defaultPayload.getUserId().toString();
} catch (io.jsonwebtoken.JwtException e) {
try {
session.close();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
// 操作api包装
GunsSocketOperator gunsSocketOperator = new GunsSocketOperator(session);
// 回复消息
WebSocketMessageDTO replyMsg = new WebSocketMessageDTO();
replyMsg.setServerMsgType(ServerMessageTypeEnum.SYS_REPLY_MSG_TYPE.getCode());
replyMsg.setToUserId(userId);
// 创建会话对象
SocketSession<GunsSocketOperator> socketSession = new SocketSession<>();
try {
// 设置回复内容
replyMsg.setData(session.getId());
socketSession.setSessionId(session.getId());
socketSession.setUserId(userId);
socketSession.setSocketOperatorApi(gunsSocketOperator);
socketSession.setToken(token);
socketSession.setConnectionTime(System.currentTimeMillis());
// 维护会话
SessionCenter.addSocketSession(socketSession);
} finally {
// 回复消息
gunsSocketOperator.writeAndFlush(replyMsg);
// 触发首次连接回调
SocketMsgCallbackInterface socketMsgCallbackInterface = SocketMessageCenter.getSocketMsgCallbackInterface(SystemMessageTypeEnum.SYS_LISTENER_ONOPEN.getCode());
if (ObjectUtil.isNotEmpty(socketMsgCallbackInterface)) {
// 触发回调
socketMsgCallbackInterface.callback(SystemMessageTypeEnum.SYS_LISTENER_ONOPEN.getCode(), null, socketSession);
}
}
}
/**
*
*
* @param session
* @author majianguo
* @since 2021/6/21 5:14
**/
@OnClose
public void onClose(Session session) {
try {
SocketSession<GunsSocketOperator> socketSession = SessionCenter.getSessionBySessionId(session.getId());
// 触发首次连接回调
SocketMsgCallbackInterface socketMsgCallbackInterface = SocketMessageCenter.getSocketMsgCallbackInterface(SystemMessageTypeEnum.SYS_LISTENER_ONCLOSE.getCode());
if (ObjectUtil.isNotEmpty(socketSession) && ObjectUtil.isNotEmpty(socketMsgCallbackInterface)) {
// 触发回调
socketMsgCallbackInterface.callback(SystemMessageTypeEnum.SYS_LISTENER_ONCLOSE.getCode(), null, socketSession);
}
} finally {
SessionCenter.deleteById(session.getId());
}
}
/**
*
*
* @param message  
* @param socketChannel
* @author majianguo
* @since 2021/6/21 5:14
**/
@OnMessage
public void onMessage(String message, Session socketChannel) {
// 转换为Java对象
WebSocketMessageDTO WebSocketMessageDTO = JSON.parseObject(message, WebSocketMessageDTO.class);
// 维护通道是否已初始化
SocketSession<GunsSocketOperator> socketSession = SessionCenter.getSessionBySessionId(socketChannel.getId());
// 心跳包
if (ObjectUtil.isNotEmpty(socketSession) && ClientMessageTypeEnum.USER_HEART.getCode().equals(WebSocketMessageDTO.getClientMsgType())) {
// 更新会话最后活跃时间
if (ObjectUtil.isNotEmpty(socketSession)) {
socketSession.setLastActiveTime(System.currentTimeMillis());
}
return;
}
// 用户ID为空不处理直接跳过
if (ObjectUtil.isEmpty(WebSocketMessageDTO.getFormUserId())) {
return;
}
// 会话建立成功执行业务逻辑
if (ObjectUtil.isNotEmpty(socketSession)) {
// 更新最后会话时间
socketSession.setLastActiveTime(System.currentTimeMillis());
// 找到该消息的处理器
SocketMsgCallbackInterface socketMsgCallbackInterface = SocketMessageCenter.getSocketMsgCallbackInterface(WebSocketMessageDTO.getClientMsgType());
if (ObjectUtil.isNotEmpty(socketMsgCallbackInterface)) {
// 触发回调
socketMsgCallbackInterface.callback(WebSocketMessageDTO.getClientMsgType(), WebSocketMessageDTO, socketSession);
} else {
socketChannel.getAsyncRemote().sendText("{\"serverMsgType\":\"404\"}");
}
}
}
/**
*
*
* @param session
* @param error  
* @author majianguo
* @since 2021/6/21 5:14
**/
@OnError
public void onError(Session session, Throwable error) {
SocketSession<GunsSocketOperator> socketSession = SessionCenter.getSessionBySessionId(session.getId());
// 触发首次连接回调
SocketMsgCallbackInterface socketMsgCallbackInterface = SocketMessageCenter.getSocketMsgCallbackInterface(SystemMessageTypeEnum.SYS_LISTENER_ONERROR.getCode());
if (ObjectUtil.isNotEmpty(socketMsgCallbackInterface)) {
// 触发回调
socketMsgCallbackInterface.callback(SystemMessageTypeEnum.SYS_LISTENER_ONERROR.getCode(), error, socketSession);
}
}
}

View File

@ -1,145 +0,0 @@
package cn.stylefeng.roses.kernel.socket.business.websocket.session;
import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.roses.kernel.socket.api.session.pojo.SocketSession;
import cn.stylefeng.roses.kernel.socket.business.websocket.operator.channel.GunsSocketOperator;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
*
* <p>
*
*
* @author majianguo
* @since 2021/6/1 1:43
*/
public class SessionCenter {
/**
*
*/
private static ConcurrentMap<String, List<SocketSession<GunsSocketOperator>>> socketSessionMap = new ConcurrentHashMap<>();
/**
*
*
* @return {@link ConcurrentMap< String, SocketSession<GunsSocketOperator>>}
* @author majianguo
* @since 2021/6/1 2:13
**/
public static ConcurrentMap<String, List<SocketSession<GunsSocketOperator>>> getSocketSessionMap() {
return socketSessionMap;
}
/**
* ID
*
* @param userId ID
* @return {@link SocketSession <GunsSocketOperator>}
* @author majianguo
* @since 2021/6/1 1:48
**/
public static List<SocketSession<GunsSocketOperator>> getSessionByUserId(String userId) {
return socketSessionMap.get(userId);
}
/**
* ID
*
* @param userId ID
* @return {@link SocketSession <GunsSocketOperator>}
* @author majianguo
* @since 2021/6/1 1:48
**/
public static List<SocketSession<GunsSocketOperator>> getSessionByUserIdAndMsgType(String userId) {
return socketSessionMap.get(userId);
}
/**
* ID
*
* @param sessionId ID
* @return {@link SocketSession <GunsSocketOperator>}
* @author majianguo
* @since 2021/6/1 1:48
**/
public static SocketSession<GunsSocketOperator> getSessionBySessionId(String sessionId) {
Set<Map.Entry<String, List<SocketSession<GunsSocketOperator>>>> entrySet = socketSessionMap.entrySet();
for (Map.Entry<String, List<SocketSession<GunsSocketOperator>>> stringListEntry : entrySet) {
List<SocketSession<GunsSocketOperator>> stringListEntryValue = stringListEntry.getValue();
for (SocketSession<GunsSocketOperator> socketSession : stringListEntryValue) {
if (sessionId.equals(socketSession.getSessionId())) {
return socketSession;
}
}
}
return null;
}
/**
*
*
* @param socketSession
* @author majianguo
* @since 2021/6/1 1:49
**/
public static void addSocketSession(SocketSession<GunsSocketOperator> socketSession) {
List<SocketSession<GunsSocketOperator>> socketSessions = socketSessionMap.get(socketSession.getUserId());
if (ObjectUtil.isEmpty(socketSessions)) {
socketSessions = Collections.synchronizedList(new ArrayList<>());
socketSessionMap.put(socketSession.getUserId(), socketSessions);
}
socketSessions.add(socketSession);
}
/**
*
*
* @param sessionId ID
* @author majianguo
* @since 2021/6/1 3:25
**/
public static void closed(String sessionId) {
// 删除维护关系
SocketSession<GunsSocketOperator> operatorSocketSession = getSessionBySessionId(sessionId);
if (ObjectUtil.isNotEmpty(operatorSocketSession)) {
operatorSocketSession.getSocketOperatorApi().close();
}
}
/**
*
*
* @param sessionId ID
* @return {@link cn.stylefeng.roses.kernel.socket.api.session.pojo.SocketSession<cn.stylefeng.roses.kernel.socket.business.websocket.operator.channel.GunsSocketOperator>}
* @author majianguo
* @since 2021/8/30 9:20
**/
public static SocketSession<GunsSocketOperator> deleteById(String sessionId) {
// 获取所有人员的连接会话信息
Set<Map.Entry<String, List<SocketSession<GunsSocketOperator>>>> entrySet = socketSessionMap.entrySet();
Iterator<Map.Entry<String, List<SocketSession<GunsSocketOperator>>>> iterator = entrySet.iterator();
while (iterator.hasNext()) {
Map.Entry<String, List<SocketSession<GunsSocketOperator>>> next = iterator.next();
List<SocketSession<GunsSocketOperator>> value = next.getValue();
if (ObjectUtil.isNotEmpty(value)) {
// 找出该人员的指定会话信息
Iterator<SocketSession<GunsSocketOperator>> socketSessionIterator = value.iterator();
while (socketSessionIterator.hasNext()) {
SocketSession<GunsSocketOperator> operatorSocketSession = socketSessionIterator.next();
if (operatorSocketSession.getSessionId().equals(sessionId)) {
// 在列表中删除
socketSessionIterator.remove();
return operatorSocketSession;
}
}
}
}
return null;
}
}

View File

@ -1 +0,0 @@
Socket的spring boot自动加载模块

View File

@ -1,29 +0,0 @@
<?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>cn.stylefeng.roses</groupId>
<artifactId>kernel-d-socket</artifactId>
<version>8.1.0</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>socket-spring-boot-starter</artifactId>
<packaging>jar</packaging>
<dependencies>
<!-- WebSocket模块 -->
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>socket-business-websocket</artifactId>
<version>${roses.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -1,54 +0,0 @@
/*
* Copyright [2020-2030] [https://www.stylefeng.cn]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*
* GunsAPACHE LICENSE 2.0使
*
* 1.LICENSE
* 2.Guns
* 3.
* 4. https://gitee.com/stylefeng/guns
* 5. https://gitee.com/stylefeng/guns
* 6.
*/
package cn.stylefeng.roses.kernel.socket.starter;
import cn.stylefeng.roses.kernel.socket.api.SocketOperatorApi;
import cn.stylefeng.roses.kernel.socket.business.websocket.operator.WebSocketOperator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Socket
*
* @author majianguo
* @since 2021/6/2 5:48
*/
@Configuration
public class ProjectSocketAutoConfiguration {
/**
* Socket
*
* @author majianguo
* @since 2021/6/2 5:48
**/
@Bean
@ConditionalOnMissingBean(SocketOperatorApi.class)
public SocketOperatorApi socketOperatorApi() {
return new WebSocketOperator();
}
}

View File

@ -1,2 +0,0 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.stylefeng.roses.kernel.socket.starter.ProjectSocketAutoConfiguration

View File

@ -117,13 +117,6 @@
<version>${roses.version}</version>
</dependency>
<!--Socket模块-->
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>socket-spring-boot-starter</artifactId>
<version>${roses.version}</version>
</dependency>
<!--wrapper工具-->
<dependency>
<groupId>cn.stylefeng.roses</groupId>

View File

@ -73,9 +73,6 @@
<!--sms模块-->
<module>kernel-d-sms</module>
<!-- Socket模块 -->
<module>kernel-d-socket</module>
<!--定时任务模块-->
<module>kernel-d-timer</module>