【Java】基于 springboot websocket 的 demo
基于 springboot websocket 的 demo
yemingfeng发布于 2 月 1 日
基于 springboot websocket 的 demo
地址
https://github.com/yemingfeng...
功能列表
- 分布式
- 同一帐号多设备登录
- 群聊
- 多设备
- 简单鉴权
- 心跳检查
依赖
- maven
- jdk11
- redis
redis 配置
redis 默认使用 localhost:6379。如果需要修改 host:port,可以修改 application.yml
<br/>
redis 仅仅用于存储用户 username / password
源码分析
Auth 过程
String username = ((ServletServerHttpRequest) request).getServletRequest().getParameter(USERNAME);
String password = ((ServletServerHttpRequest) request)
.getServletRequest().getParameter(PASSWORD);
User user = userService.register(username, password);
// 将 user 设置到 attributes 中
attributes.put(USER, user);
return true;
连接创建
// 1. 添加 sessionsessionService.add(session);// 2. 按 username + sessionId 生成 redis key,并进行订阅,这样做可以支持多设备同一个帐号登录
MessageListener messageListener = (message, pattern) -> {
log.info("Redis sub receive: [{}]", new String(message.getBody()));
try {
session.sendMessage(new TextMessage(message.getBody()));
} catch (IOException e) {
log.error("", e);
}
};
redisMessageListenerContainer.addMessageListener(messageListener,
new ChannelTopic(genSubKey(session)));
// 由于 session 会断开,需要保存下来,以待 removeListenermessageListenerMap.put(session, messageListener);
监听消息
// 获取所有在线的 session,然后通过 redis pub 功能转发消息sessionService.getSessions()
.forEach(session -> subPubService.pub(session, textMessage));
心跳检查
// 核心逻辑是一个定时任务,通过延时队列 poll 实现。// 其中 HeartbeatSessionTask 封装了 session 和对应的过期时间
this.executorService.submit(() -> {
while (true) {
try {
HeartbeatSessionTask task; while ((task = queue.poll()) != null) {
task.getSession().close();
log.warn("[{}] is dead, so close", SessionUtil.getUsernameFromSession(task.session));
}
} catch (Exception e) {
log.error("", e);
}
Thread.sleep(TimeUnit.SECONDS.toMillis(1));
}
});
使用
服务端启动
启动后,会监听 localhost:8080 端口
<br/>
其中,websocket url 为 ws:localhost:8080/ws
<br/>
获取在线用户数接口为 http://localhost:8080/session/page
shell 测试
使用 wscat 测试
wscat -c 'ws://localhost:8080/ws?username=aiden&password=123'
前端测试
由于有简单的帐号体系,链接时需要制定 username / password,若 username 不存在,则直接注册成功;否则会判断 username / password 是否匹配
<br/>
如 ws://localhost:8080/ws?username=aiden&password=123 才能进行连接
图示:
redisjavaspringwebsocketspringboot
阅读 9更新于 2 月 1 日
本作品系原创,采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议
yemingfeng
1 声望
0 粉丝
yemingfeng
1 声望
0 粉丝
宣传栏
目录
基于 springboot websocket 的 demo
地址
https://github.com/yemingfeng...
功能列表
- 分布式
- 同一帐号多设备登录
- 群聊
- 多设备
- 简单鉴权
- 心跳检查
依赖
- maven
- jdk11
- redis
redis 配置
redis 默认使用 localhost:6379。如果需要修改 host:port,可以修改 application.yml
<br/>
redis 仅仅用于存储用户 username / password
源码分析
Auth 过程
String username = ((ServletServerHttpRequest) request).getServletRequest().getParameter(USERNAME);
String password = ((ServletServerHttpRequest) request)
.getServletRequest().getParameter(PASSWORD);
User user = userService.register(username, password);
// 将 user 设置到 attributes 中
attributes.put(USER, user);
return true;
连接创建
// 1. 添加 sessionsessionService.add(session);// 2. 按 username + sessionId 生成 redis key,并进行订阅,这样做可以支持多设备同一个帐号登录
MessageListener messageListener = (message, pattern) -> {
log.info("Redis sub receive: [{}]", new String(message.getBody()));
try {
session.sendMessage(new TextMessage(message.getBody()));
} catch (IOException e) {
log.error("", e);
}
};
redisMessageListenerContainer.addMessageListener(messageListener,
new ChannelTopic(genSubKey(session)));
// 由于 session 会断开,需要保存下来,以待 removeListenermessageListenerMap.put(session, messageListener);
监听消息
// 获取所有在线的 session,然后通过 redis pub 功能转发消息sessionService.getSessions()
.forEach(session -> subPubService.pub(session, textMessage));
心跳检查
// 核心逻辑是一个定时任务,通过延时队列 poll 实现。// 其中 HeartbeatSessionTask 封装了 session 和对应的过期时间
this.executorService.submit(() -> {
while (true) {
try {
HeartbeatSessionTask task; while ((task = queue.poll()) != null) {
task.getSession().close();
log.warn("[{}] is dead, so close", SessionUtil.getUsernameFromSession(task.session));
}
} catch (Exception e) {
log.error("", e);
}
Thread.sleep(TimeUnit.SECONDS.toMillis(1));
}
});
使用
服务端启动
启动后,会监听 localhost:8080 端口
<br/>
其中,websocket url 为 ws:localhost:8080/ws
<br/>
获取在线用户数接口为 http://localhost:8080/session/page
shell 测试
使用 wscat 测试
wscat -c 'ws://localhost:8080/ws?username=aiden&password=123'
前端测试
由于有简单的帐号体系,链接时需要制定 username / password,若 username 不存在,则直接注册成功;否则会判断 username / password 是否匹配
<br/>
如 ws://localhost:8080/ws?username=aiden&password=123 才能进行连接
图示:
以上是 【Java】基于 springboot websocket 的 demo 的全部内容, 来源链接: utcz.com/a/111809.html
得票时间