mirror of
https://gitee.com/dromara/sa-token.git
synced 2025-06-28 13:34:18 +08:00
Web-Socket 鉴权示例
This commit is contained in:
parent
fbc139b430
commit
40a5cdc6dc
12
sa-token-demo/sa-token-demo-websocket-spring/.gitignore
vendored
Normal file
12
sa-token-demo/sa-token-demo-websocket-spring/.gitignore
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
target/
|
||||
|
||||
node_modules/
|
||||
bin/
|
||||
.settings/
|
||||
unpackage/
|
||||
.classpath
|
||||
.project
|
||||
|
||||
.idea/
|
||||
|
||||
.factorypath
|
69
sa-token-demo/sa-token-demo-websocket-spring/pom.xml
Normal file
69
sa-token-demo/sa-token-demo-websocket-spring/pom.xml
Normal file
@ -0,0 +1,69 @@
|
||||
<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>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-demo-websocket-spring</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
||||
<!-- SpringBoot -->
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.0.0.RELEASE</version>
|
||||
<!-- <version>1.5.9.RELEASE</version> -->
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
<!-- 定义sa-token版本号 -->
|
||||
<properties>
|
||||
<sa-token-version>1.29.0</sa-token-version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- SpringBoot依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- WebScoket 依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Sa-Token 权限认证, 在线文档:http://sa-token.dev33.cn/ -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot-starter</artifactId>
|
||||
<version>${sa-token-version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Sa-Token整合 Redis (使用jackson序列化方式) -->
|
||||
<!-- <dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-dao-redis-jackson</artifactId>
|
||||
<version>${sa-token-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
</dependency> -->
|
||||
|
||||
<!-- @ConfigurationProperties -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
</project>
|
@ -0,0 +1,32 @@
|
||||
package com.pj;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
import cn.dev33.satoken.SaManager;
|
||||
|
||||
/**
|
||||
* Sa-Token 整合 WebSocket 鉴权示例
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class SaTokenWebSocketSpringApplication {
|
||||
|
||||
/*
|
||||
* 1、访问登录接口,拿到会话Token:
|
||||
* http://localhost:8081/acc/doLogin?name=zhang&pwd=123456
|
||||
*
|
||||
* 2、找一个WebSocket在线测试页面进行连接,
|
||||
* 例如:
|
||||
* https://www.bejson.com/httputil/websocket/
|
||||
* 然后连接地址:
|
||||
* ws://localhost:8081/ws-connect?satoken=2e6db38f-1e78-40bc-aa8f-e8f1f77fbef5
|
||||
*/
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SaTokenWebSocketSpringApplication.class, args);
|
||||
System.out.println("\n启动成功:Sa-Token配置如下:" + SaManager.getConfig());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.pj.test;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.util.SaResult;
|
||||
|
||||
/**
|
||||
* 登录测试
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/acc/")
|
||||
public class LoginController {
|
||||
|
||||
// 测试登录 ---- http://localhost:8081/acc/doLogin?name=zhang&pwd=123456
|
||||
@RequestMapping("doLogin")
|
||||
public SaResult doLogin(String name, String pwd) {
|
||||
// 此处仅作模拟示例,真实项目需要从数据库中查询数据进行比对
|
||||
if("zhang".equals(name) && "123456".equals(pwd)) {
|
||||
StpUtil.login(10001);
|
||||
return SaResult.ok("登录成功").set("token", StpUtil.getTokenValue());
|
||||
}
|
||||
return SaResult.error("登录失败");
|
||||
}
|
||||
|
||||
// 查询登录状态 ---- http://localhost:8081/acc/isLogin
|
||||
@RequestMapping("isLogin")
|
||||
public SaResult isLogin() {
|
||||
return SaResult.ok("是否登录:" + StpUtil.isLogin());
|
||||
}
|
||||
|
||||
// 查询 Token 信息 ---- http://localhost:8081/acc/tokenInfo
|
||||
@RequestMapping("tokenInfo")
|
||||
public SaResult tokenInfo() {
|
||||
return SaResult.data(StpUtil.getTokenInfo());
|
||||
}
|
||||
|
||||
// 测试注销 ---- http://localhost:8081/acc/logout
|
||||
@RequestMapping("logout")
|
||||
public SaResult logout() {
|
||||
StpUtil.logout();
|
||||
return SaResult.ok();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
package com.pj.ws;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* 处理 WebSocket 连接
|
||||
*
|
||||
* @author kong
|
||||
* @date: 2022-2-11
|
||||
*/
|
||||
public class MyWebSocketHandler extends TextWebSocketHandler {
|
||||
|
||||
/**
|
||||
* 固定前缀
|
||||
*/
|
||||
private static final String USER_ID = "user_id_";
|
||||
|
||||
/**
|
||||
* 存放Session集合,方便推送消息
|
||||
*/
|
||||
private static ConcurrentHashMap<String, WebSocketSession> webSocketSessionMaps = new ConcurrentHashMap<>();
|
||||
|
||||
// 监听:连接开启
|
||||
@Override
|
||||
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
|
||||
|
||||
// put到集合,方便后续操作
|
||||
String userId = session.getAttributes().get("userId").toString();
|
||||
webSocketSessionMaps.put(USER_ID + userId, session);
|
||||
|
||||
|
||||
// 给个提示
|
||||
String tips = "Web-Socket 连接成功,sid=" + session.getId() + ",userId=" + userId;
|
||||
System.out.println(tips);
|
||||
sendMessage(session, tips);
|
||||
}
|
||||
|
||||
// 监听:连接关闭
|
||||
@Override
|
||||
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
|
||||
// 从集合移除
|
||||
String userId = session.getAttributes().get("userId").toString();
|
||||
webSocketSessionMaps.remove(USER_ID + userId);
|
||||
|
||||
// 给个提示
|
||||
String tips = "Web-Socket 连接关闭,sid=" + session.getId() + ",userId=" + userId;
|
||||
System.out.println(tips);
|
||||
}
|
||||
|
||||
// 收到消息
|
||||
@Override
|
||||
public void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
|
||||
System.out.println("sid为:" + session.getId() + ",发来:" + message);
|
||||
}
|
||||
|
||||
// -----------
|
||||
|
||||
// 向指定客户端推送消息
|
||||
public static void sendMessage(WebSocketSession session, String message) {
|
||||
try {
|
||||
System.out.println("向sid为:" + session.getId() + ",发送:" + message);
|
||||
session.sendMessage(new TextMessage(message));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
// 向指定用户推送消息
|
||||
public static void sendMessage(long userId, String message) {
|
||||
WebSocketSession session = webSocketSessionMaps.get(USER_ID + userId);
|
||||
if(session != null) {
|
||||
sendMessage(session, message);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,30 @@
|
||||
package com.pj.ws;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* WebSocket 相关配置
|
||||
*
|
||||
* @author kong
|
||||
* @date: 2022-2-11
|
||||
*/
|
||||
@Configuration
|
||||
@EnableWebSocket
|
||||
public class WebSocketConfig implements WebSocketConfigurer {
|
||||
|
||||
// 注册 WebSocket 处理器
|
||||
@Override
|
||||
public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
|
||||
webSocketHandlerRegistry
|
||||
// WebSocket 连接处理器
|
||||
.addHandler(new MyWebSocketHandler(), "/ws-connect")
|
||||
// WebSocket 拦截器
|
||||
.addInterceptors(new WebSocketInterceptor())
|
||||
// 允许跨域
|
||||
.setAllowedOrigins("*");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package com.pj.ws;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.http.server.ServerHttpRequest;
|
||||
import org.springframework.http.server.ServerHttpResponse;
|
||||
import org.springframework.web.socket.WebSocketHandler;
|
||||
import org.springframework.web.socket.server.HandshakeInterceptor;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
|
||||
/**
|
||||
* WebSocket 握手的前置拦截器
|
||||
*
|
||||
* @author kong
|
||||
* @date: 2022-2-11
|
||||
*/
|
||||
public class WebSocketInterceptor implements HandshakeInterceptor {
|
||||
|
||||
// 握手之前触发 (return true 才会握手成功 )
|
||||
@Override
|
||||
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler,
|
||||
Map<String, Object> attr) {
|
||||
|
||||
System.out.println("---- 握手之前触发 " + StpUtil.getTokenValue());
|
||||
|
||||
// 未登录情况下拒绝握手
|
||||
if(StpUtil.isLogin() == false) {
|
||||
System.out.println("---- 未授权客户端,连接失败");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 标记 userId,握手成功
|
||||
attr.put("userId", StpUtil.getLoginIdAsLong());
|
||||
return true;
|
||||
}
|
||||
|
||||
// 握手之后触发
|
||||
@Override
|
||||
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
|
||||
Exception exception) {
|
||||
System.out.println("---- 握手之后触发 ");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
# 端口
|
||||
server:
|
||||
port: 8081
|
||||
|
||||
# sa-token配置
|
||||
sa-token:
|
||||
# token名称 (同时也是cookie名称)
|
||||
token-name: satoken
|
||||
# token有效期,单位s 默认30天, -1代表永不过期
|
||||
timeout: 2592000
|
||||
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
|
||||
activity-timeout: -1
|
||||
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
|
||||
is-concurrent: true
|
||||
# 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
|
||||
is-share: true
|
||||
# token风格
|
||||
token-style: uuid
|
||||
# 是否输出操作日志
|
||||
is-log: false
|
||||
|
||||
spring:
|
||||
# redis配置
|
||||
redis:
|
||||
# Redis数据库索引(默认为0)
|
||||
database: 0
|
||||
# Redis服务器地址
|
||||
host: 127.0.0.1
|
||||
# Redis服务器连接端口
|
||||
port: 6379
|
||||
# Redis服务器连接密码(默认为空)
|
||||
password:
|
||||
# 连接超时时间
|
||||
timeout: 10s
|
||||
lettuce:
|
||||
pool:
|
||||
# 连接池最大连接数
|
||||
max-active: 200
|
||||
# 连接池最大阻塞等待时间(使用负值表示没有限制)
|
||||
max-wait: -1ms
|
||||
# 连接池中的最大空闲连接
|
||||
max-idle: 10
|
||||
# 连接池中的最小空闲连接
|
||||
min-idle: 0
|
||||
|
||||
|
||||
|
||||
|
||||
|
12
sa-token-demo/sa-token-demo-websocket/.gitignore
vendored
Normal file
12
sa-token-demo/sa-token-demo-websocket/.gitignore
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
target/
|
||||
|
||||
node_modules/
|
||||
bin/
|
||||
.settings/
|
||||
unpackage/
|
||||
.classpath
|
||||
.project
|
||||
|
||||
.idea/
|
||||
|
||||
.factorypath
|
69
sa-token-demo/sa-token-demo-websocket/pom.xml
Normal file
69
sa-token-demo/sa-token-demo-websocket/pom.xml
Normal file
@ -0,0 +1,69 @@
|
||||
<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>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-demo-websocket</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
||||
<!-- SpringBoot -->
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.0.0.RELEASE</version>
|
||||
<!-- <version>1.5.9.RELEASE</version> -->
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
<!-- 定义sa-token版本号 -->
|
||||
<properties>
|
||||
<sa-token-version>1.29.0</sa-token-version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- SpringBoot依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- WebScoket 依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Sa-Token 权限认证, 在线文档:http://sa-token.dev33.cn/ -->
|
||||
<dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-spring-boot-starter</artifactId>
|
||||
<version>${sa-token-version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Sa-Token整合 Redis (使用jackson序列化方式) -->
|
||||
<!-- <dependency>
|
||||
<groupId>cn.dev33</groupId>
|
||||
<artifactId>sa-token-dao-redis-jackson</artifactId>
|
||||
<version>${sa-token-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-pool2</artifactId>
|
||||
</dependency> -->
|
||||
|
||||
<!-- @ConfigurationProperties -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
</project>
|
@ -0,0 +1,32 @@
|
||||
package com.pj;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
import cn.dev33.satoken.SaManager;
|
||||
|
||||
/**
|
||||
* Sa-Token 整合 WebSocket 鉴权示例
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class SaTokenWebSocketApplication {
|
||||
|
||||
/*
|
||||
* 1、访问登录接口,拿到会话Token:
|
||||
* http://localhost:8081/acc/doLogin?name=zhang&pwd=123456
|
||||
*
|
||||
* 2、找一个WebSocket在线测试页面进行连接,
|
||||
* 例如:
|
||||
* https://www.bejson.com/httputil/websocket/
|
||||
* 然后连接地址:
|
||||
* ws://localhost:8081/ws-connect/2e6db38f-1e78-40bc-aa8f-e8f1f77fbef5
|
||||
*/
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SaTokenWebSocketApplication.class, args);
|
||||
System.out.println("\n启动成功:Sa-Token配置如下:" + SaManager.getConfig());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.pj.test;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.util.SaResult;
|
||||
|
||||
/**
|
||||
* 登录测试
|
||||
* @author kong
|
||||
*
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/acc/")
|
||||
public class LoginController {
|
||||
|
||||
// 测试登录 ---- http://localhost:8081/acc/doLogin?name=zhang&pwd=123456
|
||||
@RequestMapping("doLogin")
|
||||
public SaResult doLogin(String name, String pwd) {
|
||||
// 此处仅作模拟示例,真实项目需要从数据库中查询数据进行比对
|
||||
if("zhang".equals(name) && "123456".equals(pwd)) {
|
||||
StpUtil.login(10001);
|
||||
return SaResult.ok("登录成功").set("token", StpUtil.getTokenValue());
|
||||
}
|
||||
return SaResult.error("登录失败");
|
||||
}
|
||||
|
||||
// 查询登录状态 ---- http://localhost:8081/acc/isLogin
|
||||
@RequestMapping("isLogin")
|
||||
public SaResult isLogin() {
|
||||
return SaResult.ok("是否登录:" + StpUtil.isLogin());
|
||||
}
|
||||
|
||||
// 查询 Token 信息 ---- http://localhost:8081/acc/tokenInfo
|
||||
@RequestMapping("tokenInfo")
|
||||
public SaResult tokenInfo() {
|
||||
return SaResult.data(StpUtil.getTokenInfo());
|
||||
}
|
||||
|
||||
// 测试注销 ---- http://localhost:8081/acc/logout
|
||||
@RequestMapping("logout")
|
||||
public SaResult logout() {
|
||||
StpUtil.logout();
|
||||
return SaResult.ok();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.pj.ws;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
|
||||
|
||||
/**
|
||||
* 开启WebSocket支持
|
||||
*/
|
||||
@Configuration
|
||||
public class WebSocketConfig {
|
||||
|
||||
@Bean
|
||||
public ServerEndpointExporter serverEndpointExporter() {
|
||||
return new ServerEndpointExporter();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
package com.pj.ws;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.websocket.OnClose;
|
||||
import javax.websocket.OnError;
|
||||
import javax.websocket.OnMessage;
|
||||
import javax.websocket.OnOpen;
|
||||
import javax.websocket.Session;
|
||||
import javax.websocket.server.PathParam;
|
||||
import javax.websocket.server.ServerEndpoint;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import cn.dev33.satoken.exception.SaTokenException;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.dev33.satoken.util.SaFoxUtil;
|
||||
|
||||
/**
|
||||
* WebSocket 连接测试
|
||||
*/
|
||||
@Component
|
||||
@ServerEndpoint("/ws-connect/{satoken}")
|
||||
public class WebSocketConnect {
|
||||
|
||||
/**
|
||||
* 固定前缀
|
||||
*/
|
||||
private static final String USER_ID = "user_id_";
|
||||
|
||||
/**
|
||||
* 存放Session集合,方便推送消息 (javax.websocket.Session)
|
||||
*/
|
||||
private static ConcurrentHashMap<String, Session> sessionMap = new ConcurrentHashMap<>();
|
||||
|
||||
// 监听:连接成功
|
||||
@OnOpen
|
||||
public void onOpen(Session session, @PathParam("satoken") String satoken) throws IOException {
|
||||
|
||||
// 根据 token 获取对应的 userId
|
||||
Object loginId = StpUtil.getLoginIdByToken(satoken);
|
||||
if(loginId == null) {
|
||||
session.close();
|
||||
throw new SaTokenException("连接失败,无效Token:" + satoken);
|
||||
}
|
||||
|
||||
// put到集合,方便后续操作
|
||||
long userId = SaFoxUtil.getValueByType(loginId, long.class);
|
||||
sessionMap.put(USER_ID + userId, session);
|
||||
|
||||
// 给个提示
|
||||
String tips = "Web-Socket 连接成功,sid=" + session.getId() + ",userId=" + userId;
|
||||
System.out.println(tips);
|
||||
sendMessage(session, tips);
|
||||
}
|
||||
|
||||
// 监听: 连接关闭
|
||||
@OnClose
|
||||
public void onClose(Session session) {
|
||||
System.out.println("连接关闭,sid=" + session.getId());
|
||||
for (String key : sessionMap.keySet()) {
|
||||
if(sessionMap.get(key).getId().equals(session.getId())) {
|
||||
sessionMap.remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 监听:收到客户端发送的消息
|
||||
@OnMessage
|
||||
public void onMessage(Session session, String message) {
|
||||
System.out.println("sid为:" + session.getId() + ",发来:" + message);
|
||||
}
|
||||
|
||||
// 监听:发生异常
|
||||
@OnError
|
||||
public void onError(Session session, Throwable error) {
|
||||
System.out.println("sid为:" + session.getId() + ",发生错误");
|
||||
error.printStackTrace();
|
||||
}
|
||||
|
||||
// ---------
|
||||
|
||||
// 向指定客户端推送消息
|
||||
public static void sendMessage(Session session, String message) {
|
||||
try {
|
||||
System.out.println("向sid为:" + session.getId() + ",发送:" + message);
|
||||
session.getBasicRemote().sendText(message);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
// 向指定用户推送消息
|
||||
public static void sendMessage(long userId, String message) {
|
||||
Session session = sessionMap.get(USER_ID + userId);
|
||||
if(session != null) {
|
||||
sendMessage(session, message);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
# 端口
|
||||
server:
|
||||
port: 8081
|
||||
|
||||
# sa-token配置
|
||||
sa-token:
|
||||
# token名称 (同时也是cookie名称)
|
||||
token-name: satoken
|
||||
# token有效期,单位s 默认30天, -1代表永不过期
|
||||
timeout: 2592000
|
||||
# token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
|
||||
activity-timeout: -1
|
||||
# 是否允许同一账号并发登录 (为true时允许一起登录, 为false时新登录挤掉旧登录)
|
||||
is-concurrent: true
|
||||
# 在多人登录同一账号时,是否共用一个token (为true时所有登录共用一个token, 为false时每次登录新建一个token)
|
||||
is-share: true
|
||||
# token风格
|
||||
token-style: uuid
|
||||
# 是否输出操作日志
|
||||
is-log: false
|
||||
|
||||
spring:
|
||||
# redis配置
|
||||
redis:
|
||||
# Redis数据库索引(默认为0)
|
||||
database: 0
|
||||
# Redis服务器地址
|
||||
host: 127.0.0.1
|
||||
# Redis服务器连接端口
|
||||
port: 6379
|
||||
# Redis服务器连接密码(默认为空)
|
||||
password:
|
||||
# 连接超时时间
|
||||
timeout: 10s
|
||||
lettuce:
|
||||
pool:
|
||||
# 连接池最大连接数
|
||||
max-active: 200
|
||||
# 连接池最大阻塞等待时间(使用负值表示没有限制)
|
||||
max-wait: -1ms
|
||||
# 连接池中的最大空闲连接
|
||||
max-idle: 10
|
||||
# 连接池中的最小空闲连接
|
||||
min-idle: 0
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -120,6 +120,8 @@ implementation 'cn.dev33:sa-token-core:${sa.top.version}'
|
||||
├── sa-token-demo-sso-client-h5 // [示例] Sa-Token 集成 SSO单点登录-client应用端 (前后端分离)
|
||||
├── sa-token-demo-oauth2-server // [示例] Sa-Token 集成 OAuth2.0 (服务端)
|
||||
├── sa-token-demo-oauth2-client // [示例] Sa-Token 集成 OAuth2.0 (客户端)
|
||||
├── sa-token-demo-websocket // [示例] Sa-Token 集成 Web-Socket 鉴权示例
|
||||
├── sa-token-demo-websocket-spring // [示例] Sa-Token 集成 Web-Socket(Spring封装版) 鉴权示例
|
||||
├── sa-token-test // [测试] Sa-Token 单元测试合集
|
||||
├── sa-token-core-test // [测试] Sa-Token Core核心包单元测试
|
||||
├── sa-token-springboot-test // [测试] Sa-Token SpringBoot 整合测试
|
||||
|
Loading…
Reference in New Issue
Block a user