springboot2 -广播式WebSocket
Posted sufferingStriver
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot2 -广播式WebSocket相关的知识,希望对你有一定的参考价值。
1.WebSocket,STOMP,SockJS含义
WebSocket:WebSocket是html5开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
SockJS:SockJS 是 WebSocket 技术的一种模拟。为了应对许多浏览器不支持WebSocket协议的问题,设计了备选SockJs。开启并使SockJS后,它会优先选用Websocket协议作为传输协议,如果浏览器不支持Websocket协议,则会在其他方案中,选择一个较好的协议进行通讯。
STOMP:用于定义websocket的消息体格式.
2.springboot代码
定义websocket传输消息的内容格式。
浏览器向服务端发送消息:
package com.dyq.demo.DTO; public class SocketRequestMessage { private String requestMessage; public String getRequestMessage() { return requestMessage; } }
服务端向浏览器发送消息:
package com.dyq.demo.DTO; public class SocketResponseMessage { private String responseMessage; public SocketResponseMessage(String responseMessage){ this.responseMessage = responseMessage; } public String getResponseMessage() { return responseMessage; } }
WebSocket配置文件:
package com.dyq.demo.config; import org.springframework.context.annotation.Configuration; import org.springframework.messaging.simp.config.MessageBrokerRegistry; import org.springframework.web.socket.config.annotation.*; @Configuration @EnableWebSocketMessageBroker//启用STOMP协议来传输基于代理(message broker)的消息 public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void registerStompEndpoints(StompEndpointRegistry registry) { //注册一个stomp的节点,使用SockJS协议 registry.addEndpoint("/customendpoint").withSockJS(); } @Override public void configureMessageBroker(MessageBrokerRegistry config) { //config.setApplicationDestinationPrefixes("/app"); //使用内置的消息代理进行订阅和广播;路由消息的目标头以“/topic”或“/queue”开头。 config.enableSimpleBroker("/topic", "/queue"); } }
控制器代码:
package com.dyq.demo.controller; import com.dyq.demo.DTO.SocketRequestMessage; import com.dyq.demo.DTO.SocketResponseMessage; import org.springframework.messaging.handler.annotation.MessageMapping; import org.springframework.messaging.handler.annotation.SendTo; import org.springframework.stereotype.Controller; @Controller public class WebSocketController { @MessageMapping("/socket")//浏览器向服务器发送请求时,通过MessageMapping映射/socket地址 @SendTo("/topic/getResponse")//当服务器有消息时,会对订阅了@SendTo中路径的浏览器发送消息 public SocketResponseMessage say(SocketRequestMessage message) throws InterruptedException { Thread.sleep(3000); return new SocketResponseMessage("接收到RequestMessage:"+message.getRequestMessage()+"!"); } }
前端页面代码websocket.html:
前端需要三个js文件,大家可以到http://www.bootcdn.cn/去搜索下载
目前最新版:
sockjs.min.js:https://cdn.bootcss.com/sockjs-client/1.1.4/sockjs.min.js
stomp.min.js:https://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js
jquery.min.js:https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>websocket</title> </head> <body> <noscript>Your browser does not support javascript!</noscript> <div> <div> <button id="connect" onclick="connect()">连接</button> <button id="disconnect" onclick="disconnect()">断开连接</button><br/> <p id="connectStatus">未连接</p> <br/><br/> </div> <div id="conversation"> <label>输入发送信息</label> <input type="text" id="requestMessage"> <button id="sendMessage" onclick="sendMessage()">发送</button> <p id="responseMessage"></p> </div> </div> <script th:src="@{js/sockjs.min.js}"></script> <script th:src="@{js/stomp.min.js}"></script> <script th:src="@{js/jquery.min.js}"></script> <script type="text/javascript"> var stompClient = null; $(function () { setConnected(false); }); function setConnected(connected) { if(connected){ $("#connect").attr("disabled",true); $("#disconnect").attr("disabled",false); $("#conversation").show(); $("#connectStatus").html("已连接"); }else{ $("#connect").attr("disabled",false); $("#disconnect").attr("disabled",true); $("#conversation").hide(); $("#connectStatus").html("未连接"); } $("#responseMessage").html(); } function connect() { var socket = new SockJS("/customendpoint");//连接SockJs的endpoint-/customendpoint stompClient = Stomp.over(socket)//使用STOMP子协议的WebSocket客户端 stompClient.connect({},function (frame) { setConnected(true); console.log("Connected:"+frame); stompClient.subscribe("/topic/getResponse",function (response) { showResponseMessage(JSON.parse(response.body).responseMessage); }); }); } function disconnect() { if(stompClient!=null){ stompClient.disconnect(); setConnected(false); console.log("Disconnected") } } function showResponseMessage(message) { $("#responseMessage").html(message); } function sendMessage() { var requseMessage = $("#requestMessage").val(); console.log("requseMessage:"+requseMessage); stompClient.send("/socket",{},JSON.stringify({"requestMessage":requseMessage})); } </script> </body> </html>
需要在Mvc配置文件:
package com.dyq.demo.config; import org.apache.catalina.Context; import org.apache.catalina.connector.Connector; import org.apache.tomcat.util.descriptor.web.SecurityCollection; import org.apache.tomcat.util.descriptor.web.SecurityConstraint; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.*; @Configuration public class MVCConfig implements WebMvcConfigurer { public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("/index"); registry.addViewController("/index").setViewName("/index"); registry.addViewController("/websocket").setViewName("/websocket"); } }
运行,开多个浏览器窗口,连接上,如果一个浏览器发送消息到服务器,其他窗口能接受到信息。
然后运行效果:
以上是关于springboot2 -广播式WebSocket的主要内容,如果未能解决你的问题,请参考以下文章
小D课堂 - 零基础入门SpringBoot2.X到实战_汇总
springboot2.3.7升级到springboot2.7.2
2019刘老师教你用springboot2.x开发整合微信支付的线上教育平台带源码送springboot2.x零基础入门到高级实战教程