-
Notifications
You must be signed in to change notification settings - Fork 111
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
af22df8
commit 9970c46
Showing
10 changed files
with
665 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
...dmin-common/src/main/java/top/continew/admin/common/config/websocket/WebSocketConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||
* | ||
* 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. | ||
*/ | ||
|
||
package top.continew.admin.common.config.websocket; | ||
|
||
import jakarta.annotation.Resource; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.web.socket.config.annotation.EnableWebSocket; | ||
import org.springframework.web.socket.config.annotation.WebSocketConfigurer; | ||
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; | ||
import top.continew.admin.common.handler.MyWebSocketHandler; | ||
|
||
/** | ||
* WebSocketConfig配置 | ||
* | ||
* @author WeiRan | ||
* @since 2024.03.13 16:45 | ||
*/ | ||
@Configuration | ||
@EnableWebSocket | ||
public class WebSocketConfig implements WebSocketConfigurer { | ||
|
||
@Resource | ||
private WebsocketInterceptor customWebsocketInterceptor; | ||
|
||
@Resource | ||
private MyWebSocketHandler myWebSocketHandler; | ||
|
||
/** | ||
* 注册WebSocket处理程序并设置必要的配置。 | ||
* | ||
* @param registry 用于注册处理程序的WebSocketHandlerRegistry | ||
*/ | ||
@Override | ||
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { | ||
registry | ||
// 设置处理器处理/custom/** | ||
.addHandler(myWebSocketHandler, "/ws") | ||
// 允许跨越 | ||
.setAllowedOrigins("*") | ||
// 设置监听器 | ||
.addInterceptors(customWebsocketInterceptor); | ||
} | ||
|
||
} |
119 changes: 119 additions & 0 deletions
119
...common/src/main/java/top/continew/admin/common/config/websocket/WebsocketInterceptor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
/* | ||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||
* | ||
* 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. | ||
*/ | ||
|
||
package top.continew.admin.common.config.websocket; | ||
|
||
/** | ||
* Created by WeiRan on 2024.03.13 16:43 | ||
*/ | ||
|
||
import cn.hutool.core.util.StrUtil; | ||
import cn.hutool.extra.servlet.JakartaServletUtil; | ||
import jakarta.servlet.http.HttpServletRequest; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.server.ServerHttpRequest; | ||
import org.springframework.http.server.ServerHttpResponse; | ||
import org.springframework.http.server.ServletServerHttpRequest; | ||
import org.springframework.http.server.ServletServerHttpResponse; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.socket.WebSocketHandler; | ||
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor; | ||
import top.continew.admin.common.model.dto.LoginUser; | ||
import top.continew.admin.common.util.helper.LoginHelper; | ||
import top.continew.starter.web.util.ServletUtils; | ||
|
||
import java.util.Map; | ||
|
||
/** | ||
* 用来处理webscocket拦截器 | ||
* | ||
* @author WeiRan | ||
* @since 2024.03.13 16:45 | ||
*/ | ||
@Component | ||
@Slf4j | ||
public class WebsocketInterceptor extends HttpSessionHandshakeInterceptor { | ||
|
||
/** | ||
* 在建立 WebSocket 连接之前处理握手过程。 | ||
* | ||
* @param request HTTP 请求对象 | ||
* @param response HTTP 响应对象 | ||
* @param wsHandler WebSocket 处理程序 | ||
* @param attributes 用于存储 WebSocket 会话的自定义属性的映射 | ||
* @return 如果握手成功则返回 true,否则返回 false | ||
* @throws Exception 如果在握手过程中发生错误 | ||
*/ | ||
@Override | ||
public boolean beforeHandshake(ServerHttpRequest request, | ||
ServerHttpResponse response, | ||
WebSocketHandler wsHandler, | ||
Map<String, Object> attributes) throws Exception { | ||
ServletServerHttpRequest req = (ServletServerHttpRequest)request; | ||
ServletServerHttpResponse res = (ServletServerHttpResponse)response; | ||
|
||
HttpServletRequest httpServletRequest = ServletUtils.getRequest(); | ||
String ip = JakartaServletUtil.getClientIP(httpServletRequest); | ||
String token = req.getServletRequest().getParameter("token"); | ||
log.info("开始建立连接....token:{}", token); | ||
log.info("attributes:{}", attributes); | ||
if (StrUtil.isBlank(token)) { | ||
res.setStatusCode(HttpStatus.UNAUTHORIZED); | ||
res.getServletResponse().setContentType("application/json"); | ||
String errorMessage = "{\"error\": \"Authentication failed. Please provide valid credentials.\"}"; | ||
res.getBody().write(errorMessage.getBytes()); | ||
return false; | ||
} | ||
|
||
// 鉴权: 如果返回 false 则表示未通过 | ||
// response.setStatusCode(HttpStatus.UNAUTHORIZED); | ||
//返回 false; | ||
LoginUser loginUser = LoginHelper.getLoginUser(token); | ||
if (loginUser == null) { | ||
res.setStatusCode(HttpStatus.UNAUTHORIZED); | ||
res.getServletResponse().setContentType("application/json"); | ||
String errorMessage = "{\"error\": \"Authentication failed. Please provide valid credentials.\"}"; | ||
res.getBody().write(errorMessage.getBytes()); | ||
res.close(); | ||
return false; | ||
} | ||
attributes.put("userId", String.valueOf(loginUser.getId())); | ||
attributes.put("ip", ip); | ||
super.setCreateSession(true); | ||
return super.beforeHandshake(request, response, wsHandler, attributes); | ||
} | ||
|
||
/** | ||
* WebSocket 握手成功完成后调用此方法。 | ||
* 它记录一条消息指示连接已建立,然后调用 | ||
* 方法的超类实现。 | ||
* | ||
* @param request 表示传入 HTTP 请求的 ServerHttpRequest 对象 | ||
* @param response 表示传出 HTTP 响应的 ServerHttpResponse 对象 | ||
* @param wsHandler 将处理 WebSocket 会话的 WebSocketHandler 对象 | ||
* @param exception 在握手过程中发生的异常,如果没有异常则为 null | ||
*/ | ||
@Override | ||
public void afterHandshake(ServerHttpRequest request, | ||
ServerHttpResponse response, | ||
WebSocketHandler wsHandler, | ||
Exception exception) { | ||
log.info("连接成功...."); | ||
//其他业务代码 | ||
super.afterHandshake(request, response, wsHandler, exception); | ||
} | ||
} |
113 changes: 113 additions & 0 deletions
113
...inew-admin-common/src/main/java/top/continew/admin/common/handler/MyWebSocketHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
/* | ||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||
* | ||
* 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. | ||
*/ | ||
|
||
package top.continew.admin.common.handler; | ||
|
||
/** | ||
* Created by WeiRan on 2024.03.13 16:41 | ||
*/ | ||
|
||
import cn.hutool.core.util.StrUtil; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.socket.CloseStatus; | ||
import org.springframework.web.socket.TextMessage; | ||
import org.springframework.web.socket.WebSocketSession; | ||
import org.springframework.web.socket.handler.TextWebSocketHandler; | ||
import top.continew.admin.common.util.WsUtils; | ||
|
||
import java.io.IOException; | ||
|
||
/** | ||
* @author zhong | ||
* webscoket 处理器 | ||
*/ | ||
@Component | ||
@Slf4j | ||
public class MyWebSocketHandler extends TextWebSocketHandler { | ||
|
||
/** | ||
* 收到客户端消息时触发的回调 | ||
* | ||
* @param session 连接对象 | ||
* @param message 消息体 | ||
*/ | ||
@Override | ||
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException { | ||
log.info("接受到会话【{}】的消息:{}", session.getId(), message.getPayload()); | ||
String jsonPayload = message.getPayload(); | ||
if (StrUtil.isBlank(jsonPayload)) { | ||
log.error("接收到空消息"); | ||
return; | ||
} | ||
try { | ||
//业务逻辑处理 | ||
// WsUtils.send(session, "我收到了你的消息"); | ||
} catch (Exception e) { | ||
log.error("WebSocket消息解析失败:{}", e.getMessage(), e); | ||
WsUtils.close(session, "消息解析失败:" + e.getMessage()); | ||
} | ||
} | ||
|
||
/** | ||
* 建立连接后触发的回调 | ||
* | ||
* @param session 连接对象 | ||
* @throws Exception | ||
*/ | ||
@Override | ||
public void afterConnectionEstablished(WebSocketSession session) throws Exception { | ||
String userId = String.valueOf(session.getAttributes().get("userId")); | ||
// 将新连接添加 | ||
WsUtils.bindUser(userId, session); | ||
//在线数加1 | ||
WsUtils.onlineCount.incrementAndGet(); | ||
log.info("与用户【{}】建立了连接 当前在线人数【{}】", userId, WsUtils.onlineCount.get()); | ||
log.info("attributes:{}", session.getAttributes()); | ||
|
||
} | ||
|
||
/** | ||
* 断开连接后触发的回调 | ||
* | ||
* @param session 连接对象 | ||
* @param status 状态 | ||
* @throws Exception 异常 | ||
*/ | ||
@Override | ||
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { | ||
// 关闭连接 | ||
WsUtils.close(session, "断开连接后触发的回调"); | ||
log.info("用户【{}】断开连接,status:{},当前剩余在线人数【{}】", WsUtils.getUserId(session), status.getCode(), WsUtils.onlineCount | ||
.get()); | ||
} | ||
|
||
/** | ||
* 传输消息出错时触发的回调 | ||
* | ||
* @param session 连接对象 | ||
* @param exception 异常 | ||
* @throws Exception 异常 | ||
*/ | ||
@Override | ||
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { | ||
log.info("用户【{}】发生错误,exception:{}", session.getId(), exception.getMessage()); | ||
// 如果发送异常,则断开连接 | ||
if (session.isOpen()) { | ||
WsUtils.close(session, "传输消息出错时触发的回调"); | ||
} | ||
} | ||
} |
60 changes: 60 additions & 0 deletions
60
continew-admin-common/src/main/java/top/continew/admin/common/model/dto/WsMsg.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
/* | ||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||
* | ||
* 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. | ||
*/ | ||
|
||
package top.continew.admin.common.model.dto; | ||
|
||
import lombok.Data; | ||
|
||
import java.io.Serializable; | ||
|
||
@Data | ||
public class WsMsg implements Serializable { | ||
/** | ||
* 消息 ID | ||
*/ | ||
public String msgId; | ||
|
||
/** | ||
* 发送者 ID | ||
*/ | ||
public String fromId; | ||
|
||
/** | ||
* 发送人名称 | ||
*/ | ||
public String fromName; | ||
|
||
/** | ||
* 接受者ID | ||
*/ | ||
public String toId; | ||
|
||
/** | ||
* 消息类型 | ||
*/ | ||
public int msgType; | ||
|
||
/** | ||
* 发送消息时间戳 | ||
*/ | ||
public long sendTime; | ||
|
||
/** | ||
* 消息内容 | ||
*/ | ||
public String content; | ||
|
||
} |
Oops, something went wrong.