springboot下websocket前台后端数据长连接
2019-03-12 09:39
281 查看
首先导入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-messaging</artifactId> </dependency>
spring-security-messaging 是后面继承 AbstractSecurityWebSocketMessageBrokerConfigurer需要用到的依赖
WebSocketConfig
@Configuration @EnableWebSocketMessageBroker //此注解表示使用STOMP协议来传输基于消息代理的消息,此时可以在@Controller类中使用@MessageMapping public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void registerStompEndpoints(StompEndpointRegistry registry) { /** * 注册 Stomp的端点 * addEndpoint:添加STOMP协议的端点。这个HTTP URL是供WebSocket或SockJS客户端访问的地址 * withSockJS:指定端点使用SockJS协议 */ registry.addEndpoint("/websocket/tracker") //物流消息通道, .setAllowedOrigins("*") //允许跨域,里面路径可以设定 .withSockJS() //指定协议 .setInterceptors(httpSessionHandshakeInterceptor()) ; //设置拦截器() } @Override public void configureMessageBroker(MessageBrokerRegistry registry) { /** * 配置消息代理 * 启动简单Broker,消息的发送的地址符合配置的前缀来的消息才发送到这个broker */ registry.enableSimpleBroker("/topic","/user"); } //拦截器 @Bean public HandshakeInterceptor httpSessionHandshakeInterceptor() { return new HandshakeInterceptor() { @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception { //可以在这里先判断登录是否合法 return true; } @Override public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) { //握手成功后, } }; } }
WebsocketSecurityConfiguration
@Configuration public class WebsocketSecurityConfiguration extends AbstractSecurityWebSocketMessageBrokerConfigurer { @Override protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) { messages .nullDestMatcher().authenticated() .simpDestMatchers("/topic/**").authenticated() .simpDestMatchers("/user/**").authenticated() .simpTypeMatchers(SimpMessageType.MESSAGE, SimpMessageType.SUBSCRIBE).denyAll() // catch all .anyMessage().denyAll(); } /** * Disables CSRF for Websockets. */ @Override protected boolean sameOriginDisabled() { return true; } }
WebSocketResource
package com.gleam.shopmall.web.rest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationListener; import org.springframework.messaging.handler.annotation.MessageMapping; import org.springframework.messaging.handler.annotation.SendTo; import org.springframework.messaging.simp.SimpMessageHeaderAccessor; import org.springframework.messaging.simp.SimpMessageMappingInfo; import org.springframework.messaging.simp.SimpMessageSendingOperations; import org.springframework.stereotype.Controller; import org.springframework.web.socket.messaging.SessionDisconnectEvent; @Controller public class WebSocketResource { private static final Logger log = LoggerFactory.getLogger(WebSocketResource.class); @Autowired SimpMessageSendingOperations messagingTemplate; //此方法适用于网页聊天室,从前端接收数据,返回订阅者(前端) @MessageMapping("/welcome") //指定要接收消息的地址,类似@RequestMapping @SendTo("/topic/getResponse") //默认消息将被发送到与传入消息相同的目的地,但是目的地前面附加前缀(默认情况下为“/topic”} public String say(String message) throws Exception { return message; } //发送指定用户(直接从后端发送数据到前端) public void sendToUser(String login,String channel, String info) { log.debug("[ToUser]WEBSOCKET发送消息, username={}, info={}", login, info); this.messagingTemplate.convertAndSendToUser(login, channel, info); log.debug("[ToUser]WEBSOCKET发送消息:完成"); } //发送所有订阅的(直接从后端发送数据到前端) public void send(String channel, String info) { log.debug("[ToAll]WEBSOCKET发送消息, info={}", info); // this.messagingTemplate.convertAndSend(channel, info); this.messagingTemplate.convertAndSend("/topic/getResponse", "接收到了吗?"); log.debug("[ToAll]WEBSOCKET发送消息:完成"); } }
前端html
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8" /> <script src="http://cdn.jsdelivr.net/sockjs/0.3.4/sockjs.min.js"></script> <script src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.js"></script> <script src="http://code.jquery.com/jquery-1.7.2.min.js"></script> <script src="http://pv.sohu.com/cityjson?ie=utf-8"></script> <title>Spring Boot+WebSocket+广播式</title> <script type="text/javascript"> var stompClient = null; function setConnected(connected) { document.getElementById('connect').disabled = connected; document.getElementById('disconnect').disabled = !connected; document.getElementById('conversationDiv').style.visibility = connected ? 'visible' : 'hidden'; $('#response').html(); } function connect() { // websocket的连接地址,此值等于WebSocketConfig中registry.addEndpoint("/websocket/tracker").withSockJS()配置的地址, //这里如果是微服务或者远端,需要全路径 var socket = new SockJS('/websocket/tracker'); //1 stompClient = Stomp.over(socket);//2 stompClient.connect({}, function(frame) {//3 setConnected(true); console.log('开始进行连接Connected: ' + frame); // 客户端订阅消息的目的地址:此值等于WebSocketResource中@SendTo("/topic/getResponse")注解的里配置的值 stompClient.subscribe('/topic/getResponse', function(respnose){ //4 showResponse(respnose.body); }); }); } function disconnect() { if (stompClient != null) { stompClient.disconnect(); } setConnected(false); console.log("Disconnected"); } function sendName() { var name = $('#name').val(); stompClient.send("/welcome", {}, returnCitySN['cip'] +":"+name);// JSON.stringify(name) } function showResponse(message) { var response = $("#response"); response.html(message+"<br>" + response.html()); } </script> </head> <body "disconnect()"> <noscript><h2 style="color: red">貌似你的浏览器不支持websocket</h2></noscript> <div> <div> <button id="connect" onclick="connect();" style="color: red">连接</button> <button id="disconnect" disabled="disabled" onclick="disconnect();">断开连接</button> </div> <div id="conversationDiv"> <label>输入内容</label><input type="text" id="name" /> <button id="sendName" onclick="sendName();">发送</button> <p id="response"></p> </div> </div> </body> </html>```
相关文章推荐
- Vue+Springboot前后端分离websocket的使用
- VUE+SpringBoot+Websocket实现前后端通信案例分享
- react +axios 后端使用springboot进行跨域请求时数据丢失问题
- springboot 通过 hibernate 连接sqlserver 空间数据 位置数据
- spring boot 给前台返json数据(list)出现死循环
- springboot,后端如何获取fetch传来的数据
- Spring Boot 框架,封装后台向前台传输的数据的类 ResultVO
- SpringBoot简单连接数据库以及查询数据
- spring-boot统一处理返回给前台的数据格式(避免返回异常堆栈信息,干扰用户体验)
- 当使用ajax 由前台像后台post 数组类型数据的一些问题(基于springboot)
- idea搭建SpringBoot和AJAX前后端数据交互,含源码
- spring boot 解决后台返回 json 到前台中文乱码之后出现返回json数据报错 500
- Springboot+rabbitMQ(只连接一个rabbitMQ)数据传输实例
- SpringBoot--配置Druid连接池
- springboot之启动加载数据 CommandLineRunner 和ApplicationRunner
- 2. Spring Boot返回json数据【从零开始学Spring Boot】
- Springboot2.X集成redis集群(Lettuce)连接的方法
- Spring Boot干货系列:(八)数据存储篇-SQL关系型数据库之JdbcTemplate的使用
- Spring boot + mybatis + Vue.js + ElementUI 实现数据的增删改查实例代码(一)
- Spring JDBC-数据连接泄露解读