前言

2021春节后第一篇文章,承接之前继续完成websocket系列,本篇主要是介绍怎么基于spring-boot-starter-websocket来实现websocket。


一、项目结构

二、具体说明

1.引入maven依赖

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>

2.实现WebSocketConfigurer配置类

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {@Autowiredprivate MyWsHandler myWsHandler;@Overridepublic void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {registry.addHandler(myWsHandler, "myWs")//允许跨域.setAllowedOrigins("*");}
}

说明:
通过实现WebSocketConfigurer配置类,重写registerWebSocketHandlers方法,注册自定义的WebSocketHandler的实现类MyWsHandler,并指定类对应的websocket访问的ServerEndpoint为/myWs。
通过@EnableWebSocket注解,启动spring-boot-starter-websocket的自动化配置。

3.自定义WebSocketHandler

/*** ws消息处理类*/
@Component
@Slf4j
public class MyWsHandler extends AbstractWebSocketHandler {@Overridepublic void afterConnectionEstablished(WebSocketSession session) throws Exception {log.info("建立ws连接");WsSessionManager.add(session.getId(),session);}@Overrideprotected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {log.info("发送文本消息");// 获得客户端传来的消息String payload = message.getPayload();log.info("server 接收到消息 " + payload);session.sendMessage(new TextMessage("server 发送给的消息 " + payload + ",发送时间:" + LocalDateTime.now().toString()));}@Overrideprotected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws Exception {log.info("发送二进制消息");}@Overridepublic void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {log.error("异常处理");WsSessionManager.removeAndClose(session.getId());}@Overridepublic void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {log.info("关闭ws连接");WsSessionManager.removeAndClose(session.getId());}
}

说明:
通过继承 AbstractWebSocketHandler 类并覆盖相应方法,可以对 websocket 的事件进行处理,这里可以同原生注解的那几个注解连起来看
afterConnectionEstablished 方法是在 socket 连接成功后被触发,同原生注解里的 @OnOpen 功能。
afterConnectionClosed方法是在 socket 连接关闭后被触发,同原生注解里的 @OnClose 功能。
handleTextMessage方法是在客户端发送普通文件信息时触发,同原生注解里的 @OnMessage 功能。
handleBinaryMessage 方法是在客户端发送二进制信息时触发,同原生注解里的 @OnMessage 功能。
handleTransportError方法同原生注解里的@OnError。

除了继承AbstractWebSocketHandler类外,还有以下WebSocketHandler可供选择。
AbstractWebSocketHandler可以同时支持普通文本和二进制的消息处理。
BinaryWebSocketHandler只支持二进制消息。
TextWebSocketHandler只支持普通文本消息。

4.定时消息推送MessageJob

/*** 消息生成job*/
@Slf4j
@Component
public class MessageJob {@AutowiredWsService wsService;/*** 每5s发送*/@Scheduled(cron = "0/5 * * * * *")public void run(){try {wsService.broadcastMsg("自动生成消息 "  + LocalDateTime.now().toString());} catch (IOException e) {e.printStackTrace();}}
}

5.消息推送服务类WsService

/*** ws操作相关服务*/
@Service
@Slf4j
public class WsService {/*** 发送消息* @param session* @param text* @return* @throws IOException*/public void sendMsg(WebSocketSession session, String text) throws IOException {session.sendMessage(new TextMessage(text));}/*** 广播消息* @param text* @return* @throws IOException*/public void broadcastMsg(String text) throws IOException {for (WebSocketSession session: WsSessionManager.SESSION_POOL.values()) {session.sendMessage(new TextMessage(text));}}}

6.Session管理类WsSessionManager

@Slf4j
public class WsSessionManager {/*** 保存连接 session 的地方*/public  static ConcurrentHashMap<String, WebSocketSession> SESSION_POOL = new ConcurrentHashMap<>();/*** 添加 session** @param key*/public static void add(String key, WebSocketSession session) {// 添加 sessionSESSION_POOL.put(key, session);}/*** 删除 session,会返回删除的 session** @param key* @return*/public static WebSocketSession remove(String key) {// 删除 sessionreturn SESSION_POOL.remove(key);}/*** 删除并同步关闭连接** @param key*/public static void removeAndClose(String key) {WebSocketSession session = remove(key);if (session != null) {try {// 关闭连接session.close();} catch (IOException e) {// todo: 关闭出现异常处理e.printStackTrace();}}}/*** 获得 session** @param key* @return*/public static WebSocketSession get(String key) {// 获得 sessionreturn SESSION_POOL.get(key);}
}

7.启动类SpringWsApplication

@SpringBootApplication
@EnableScheduling
public class SpringWsApplication {public static void main(String[] args) {SpringApplication.run(SpringWsApplication.class, args);}}

8.首页index.html

发现很多小伙伴不知道调用WebSocket的前端页面怎么写,这里重新补充一下。

<!DOCTYPE HTML>
<html>
<head><title>My WebSocket</title>
</head><body>
<input id="text" type="text" />
<button onclick="send()">Send</button>
<button onclick="closeWebSocket()">Close</button>
<div id="message"></div></body><script type="text/javascript">let ws = null;//判断当前浏览器是否支持WebSocketif ('WebSocket' in window) {ws = new WebSocket("ws://localhost:8333/myWs");}else {alert('当前浏览器 Not support websocket')}//连接发生错误的回调方法ws.onerror = function () {setMessageInnerHTML("WebSocket连接发生错误");};//连接成功建立的回调方法ws.onopen = function(event) {console.log("ws调用连接成功回调方法")//ws.send("")}//接收到消息的回调方法ws.onmessage = function(message) {console.log("接收消息:" + message.data);if (typeof(message.data) == 'string') {setMessageInnerHTML(message.data);}}//ws连接断开的回调方法ws.onclose = function(e) {console.log("ws连接断开")//console.log(e)setMessageInnerHTML("ws close");}//将消息显示在网页上function setMessageInnerHTML(innerHTML) {console.log(innerHTML)document.getElementById('message').innerHTML += '接收的消息:' + innerHTML + '<br/>';}//关闭连接function closeWebSocket() {ws.close();}//发送消息function send(msg) {if(!msg){msg = document.getElementById('text').value;document.getElementById('message').innerHTML += "发送的消息:" + msg + '<br/>';ws.send(msg);}}
</script>
</html>

9.测试


总结

基于spring-boot-starter-websocket实现也非常简单,主要是3个实现步骤:
1.通过继承AbstractWebSocketHandler自定义WebSocketHandler,重写afterConnectionEstablished、handleTextMessage、handleBinaryMessage、handleTransportError、afterConnectionClosed等方法,都能和jdk的原生websocket注解对应上。
2.通过实现WebSocketConfigurer进行WebSocket的相关配置,利用WebSocketHandlerRegistry注册自定义的WebSocketHandler。
3.消息的发送主要是通过WebSocketSession来实现。

websocket系列:基于spring-boot-starter-websocket实现相关推荐

  1. 基于Spring Boot的WebSocket应用程序并捕获HTTP会话ID

    我最近参与了一个项目,我们需要捕获Websocket请求的http会话ID –原因是要确定使用相同基础HTTP会话的Websocket会话的数量. 这样做的方法基于利用新的spring-session ...

  2. Spring Boot 2.x整合Websocket(基于Spring Boot 2.x 前后端分离 iview admin vue 集成activiti工作流...

    宣传官网 xb.exrick.cn 在线Demo xboot.exrick.cn 开源版Github地址 github.com/Exrick/x-bo- 开发文档 www.kancloud.cn/ex ...

  3. SpringBoot2.x系列教程(四十五)Spring Boot集成WebSocket实现技术交流群功能

    在上篇文章中,我们了解了WebSocket的基本功能及相关概念.本篇文章中我们以具体的实例来演示,在Spring Boot中整合WebSocket,同时实现一个场景的业务场景功能. 针对在Spring ...

  4. spring boot 集成 websocket 实现消息主动推送

    前言 http协议是无状态协议,每次请求都不知道前面发生了什么,而且只可以由浏览器端请求服务器端,而不能由服务器去主动通知浏览器端,是单向的,在很多场景就不适合,比如实时的推送,消息通知或者股票等信息 ...

  5. Spring boot 实现 WebSocket服务端

    Spring boot 实现 WebSocket服务端 这里写目录标题 Spring boot 实现 WebSocket服务端 声明 准备工作 1. 配置 2. WebSocket服务类 3. 编写客 ...

  6. SpringBoot系列(22):Java生成二维码的几种实现方式(基于Spring Boot)

    原文链接:http://www.fightjava.com/web/index/blog/article/82 在一些企业级应用系统中,有时候需要为产品或者商品生成特定的专属二维码,以供一些硬件设备或 ...

  7. 基于 Spring Boot + Cloud 构建微云架构

    点击上方"Java基基",选择"设为星标" 做积极的人,而不是积极废人! 源码精品专栏 原创 | Java 2019 超神之路,很肝~ 中文详细注释的开源项目 ...

  8. 自定义依赖注解无效_最详细的自定义Spring Boot Starter开发教程

    1.前言 随着Spring的日渐臃肿,为了简化配置.开箱即用.快速集成,Spring Boot 横空出世.目前已经成为 Java 目前最火热的框架了.平常我们用Spring Boot开发web应用.S ...

  9. 自定义 Spring Boot Starter

    一.引言 什么是Spring Boot Starter呢?我们直接来看看官网是怎么介绍的吧. Starters are a set of convenient dependency descripto ...

  10. Spring boot starter

    1:Spring boot starter及项目中的类似运用 1:Spring boot starter的两种方式 引入pom文件,自动管理jar版本 根据spring.factories配置文件,加 ...

最新文章

  1. 新手神器!不用部署深度学习环境、上传数据集!(附代码视频教程)
  2. CentOS 7 yum源安装Nginx
  3. oracle 分表设计,oracle 分库分表(sharding)
  4. 某电视台晚会多机位特殊视频修复案例
  5. fedora16设置root登录
  6. unity2d随机生成物体_平面测量路径生成的4种方式
  7. SQL Server索引视图以(物化视图)及索引视图与查询重写
  8. 一个进程(Process)最多可以生成多少个线程(Thread)
  9. arcengine开发中遇到的错误汇总
  10. 企业网站电子邮件营销的优势与转化率分析
  11. MySQL中CASE WHEN的用法
  12. Matlab读nc文件
  13. 竞价被恶意点击怎么办?该怎么屏蔽?
  14. 如何快速使计算机锁屏,电脑如何一键锁屏?有急事时如何快速锁屏?[多图]
  15. contiki之list头文件
  16. 智能座舱之HUD-发展趋势深度解析
  17. c语言一些算法解题技巧,c语言常见小算法的解题思路.doc
  18. 别让懒惰,毁了你的努力!从上班混日子到月入2万
  19. 50万VPN登录凭证遭泄露,中国占11.89%
  20. 为什么用python画图_怎么用python画图

热门文章

  1. 一路狂奔的硅谷钢铁侠,终于露出脆弱与疲倦,压力焦虑直播吸大麻
  2. 样本协差阵 matlab函数,方差var、协方差cov、协方差矩阵(浅谈)(三)_函数cov...
  3. SpringBoot启动和启动成功的彩蛋logo
  4. simpleAlert.js弹出对话框插件
  5. 从前端开始——01网页三剑客(html)
  6. python名称定义怎么解决_如何解决未定义的名称错误?
  7. 错过Doge,Shib,还想错过JOMON吗?
  8. 计算机设备制造,制造计算机设备
  9. 量子计算机中信息的基本单位,重磅!成功将“人造原子”量子位,稳定的用在量子计算机上!...
  10. 怎么摆脱百度云盘限速设置