Spring Boot整合WebSocket 消息群发
WebSocket简介
Spring Boot对WebSocket提供了非常友好的支持,可以方便开发者在项目中快速集成WebSocket功能
添加依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>webjars-locator-core</artifactId> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>sockjs-client</artifactId> <version>1.1.2</version> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>stomp-websocket</artifactId> <version>2.3.3</version> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>jquery</artifactId> <version>3.3.1</version> </dependency>
spring-boot-starter-websocket依赖是Web Socket相关依赖,
其他的都是前端库,使用jar包的形式对这些前端库进行统一管理,使用webjar添加到项目中的前端库,在Spring Boot项目中已经默认添加了静态资源过滤,因此可以直接使用。
配置WebSocket:
Spring框架提供了基于WebSocket的STOMP支持,STOMP是一个简单的可互操作的协议,通常被用于通过中间服务器在客户端之间进行异步消息传递。WebSocket配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | // 自定义类WebSocketConfig继承自WebSocketMessageBrokerConfigurer进行WebSocket配置 @Configuration @EnableWebSocketMessageBroker // 开启WebSocket消息代理 public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry config) { /* * 表示设置消息代理的前缀,即如果消息的前缀是“/topic”,就会将消息转发给消息代理(broker),再由消息代理将消息广播给当前连接的客户端。 */ config.enableSimpleBroker( "/topic" , "/queue" ); /* * 表示配置一个或多个前缀,通过这些前缀过滤出需要被注解方法处理的消息 * 例如,前缀为“/app”的destination可以通过@MessageMapping注解的方法处理, * 而其他destination(例如“/ topic”“/ queue”)将被直接交给broker处理。 */ config.setApplicationDestinationPrefixes( "/app" ); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { /* * 表示定义一个前缀为“/chat”的endPoint,并开启sockjs支持, * sockjs可以解决浏览器对WebSocket的兼容性问题, * 客户端将通过这里配置的URL来建立WebSocket连接。 */ registry.addEndpoint( "/chat" ).withSockJS(); } } |
定义Controller:
定义一个Controller用来实现对消息的处理,代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | @Controller public class GreetingController { @Autowired SimpMessagingTemplate messagingTemplate; @MessageMapping ( "/hello" ) // 用来接收“/app/hello”路径发送来的消息 在注解方法中对消息进行处理后,再将消息转发到@SendTo定义的路径上 @SendTo ( "/topic/greetings" ) // @SendTo路径是一个前缀为“/topic”的路径,因此该消息将被交给消息代理broker,再由broker进行广播。 public Message greeting(Message message) { return message; } @MessageMapping ( "/chat" ) public void chat(Principal principal, Chat chat) { String from = principal.getName(); chat.setFrom(from); messagingTemplate.convertAndSendToUser(chat.getTo(), "/queue/chat" , chat); } } |
构建聊天页面:
在resources/static目录下创建chat.html页面作为聊天页面,代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | <! DOCTYPE html> < html lang="en"> < head > < meta charset="UTF-8"> < title >群聊</ title > < script src="/webjars/jquery/jquery.min.js"></ script > < script src="/webjars/sockjs-client/sockjs.min.js"></ script > < script src="/webjars/stomp-websocket/stomp.min.js"></ script > < script src="/app.js"></ script > </ head > < body > < div > < label for="name">请输入用户名:</ label > < input type="text" id="name" placeholder="用户名"> </ div > < div > < button id="connect" type="button">连接</ button > < button id="disconnect" type="button" disabled="disabled">断开连接</ button > </ div > < div id="chat" style="display: none;"> < div > < label for="name">请输入聊天内容:</ label > < input type="text" id="content" placeholder="聊天内容"> </ div > < button id="send" type="button">发送</ button > < div id="greetings"> < div id="conversation" style="display: none">群聊进行中...</ div > </ div > </ div > </ body > </ html > |
app.js是一个自定义JS,代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | var stompClient = null ; function setConnected(connected) { $( "#connect" ).prop( "disabled" , connected); $( "#disconnect" ).prop( "disabled" , !connected); if (connected) { $( "#conversation" ).show(); $( "#chat" ).show(); } else { $( "#conversation" ).hide(); $( "#chat" ).hide(); } $( "#greetings" ).html( "" ); } /** * connect方法表示建立一个WebSocket连接 */ function connect() { // 在建立WebSocket连接时,用户必须先输入用户名,然后才能建立连接 if (!$( "#name" ).val()) { return ; } var socket = new SockJS( '/chat' ); // 首先使用SockJS建立连接 stompClient = Stomp.over(socket); // 然后创建一个STOMP实例发起连接请求 stompClient.connect({}, function (frame) { setConnected( true ); // 在连接成功的回调方法中,首先调用setConnected(true);方法进行页面的设置 //然后调用STOMP中的subscribe方法订阅服务端发送回来的消息, stompClient.subscribe( '/topic/greetings' , function (greeting) { showGreeting(JSON.parse(greeting.body)); // 并将服务端发送来的消息展示出来(使用showGreeting方法)。 }); }); } function disconnect() { if (stompClient !== null ) { // 调用STOMP中的disconnect方法可以断开一个WebSocket连接。 stompClient.disconnect(); } setConnected( false ); } function sendName() { stompClient.send( "/app/hello" , {}, JSON.stringify( { 'name' : $( "#name" ).val(), 'content' : $( "#content" ).val() } )); } function showGreeting(message) { $( "#greetings" ).append( "<div>" + message.name + ":" + message.content + "</div>" ); } $( function () { $( "#connect" ).click( function () { connect(); }); $( "#disconnect" ).click( function () { disconnect(); }); $( "#send" ).click( function () { sendName(); }); }); |
测试:
接下来启动Spring Boot项目进行测试,在浏览器中输入http://localhost:8081/chat.html
文章来源: Spring Boot+Vue全栈开发实战 - 11.3 Spring Boot整合WebSocket
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律