您的位置:首页 > 编程语言 > Java开发

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>```
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: