vue+springboot 服务端主动推送消息实战

804 阅读1分钟
  • 技术栈

前端

h5 vue sockjs stomp axios

后端

SpringBoot websocket

  • 功能

    1. 服务端主动推送消息

    2. 断开后重连机制

  • 实现

不解释直接上代码,可以关注下面的相关技术群和公众号

pom文件里面引用

<dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-websocket</artifactId>    <version>2.3.3.RELEASE</version></dependency>

@Configuration@EnableWebSocketMessageBrokerpublic class WebSocketConfig implements WebSocketMessageBrokerConfigurer{    @Override    public void registerStompEndpoints(StompEndpointRegistry registry)    {        registry.setErrorHandler(this.webSocketHandler())            .addEndpoint("/api/h5/endpointstore")            .setAllowedOrigins("*")            .withSockJS();    }    @Override    public void configureMessageBroker(MessageBrokerRegistry registry)    {        registry.enableSimpleBroker("/topic", "/queue");        registry.setUserDestinationPrefix("/user");    }    @Bean    public StompSubProtocolErrorHandler webSocketHandler() {        return new WebSocketErrorHandler ();    }}

@Componentpublic class WebSocketConnectListener implements ApplicationListener<SessionConnectEvent>{    private Logger logger = LoggerFactory.getLogger(WebSocketConnectListener.class);    @Override    public void onApplicationEvent(SessionConnectEvent sessionConnectEvent)    {        StompHeaderAccessor accessor = StompHeaderAccessor.wrap(sessionConnectEvent.getMessage());        String sessionId = accessor.getSessionId();        logger.info("sessionId: {} 已连接", sessionId);    }}

@Componentpublic class WebSocketDisconnectListener implements ApplicationListener<SessionDisconnectEvent>{   private Logger logger = LoggerFactory.getLogger(WebSocketDisconnectListener.class);    @Override    public void onApplicationEvent(SessionDisconnectEvent event) {        StompHeaderAccessor sha = StompHeaderAccessor.wrap(event.getMessage());        String sessionId = sha.getSessionId();        logger.info("sessionId: {} 已断开", sessionId);    }}

public class WebSocketErrorHandler    extends StompSubProtocolErrorHandler {   private Logger logger = LoggerFactory.getLogger(WebSocketErrorHandler.class);    public WebSocketErrorHandler() {        super();    }    @Override    public Message<byte[]> handleClientMessageProcessingError(Message<byte[]> clientMessage, Throwable ex) {        logger.error("handleClientMessageProcessingError:clientMessage-" + clientMessage + ", error-" + ex.getMessage());        return super.handleClientMessageProcessingError(clientMessage, ex);    }    @Override    public Message<byte[]> handleErrorMessageToClient(Message<byte[]> errorMessage) {        logger.error("handleErrorMessageToClient:errorMessage-" + errorMessage);        return super.handleErrorMessageToClient(errorMessage);    }    @Override    protected Message<byte[]> handleInternal(StompHeaderAccessor errorHeaderAccessor, byte[] errorPayload, Throwable cause, StompHeaderAccessor clientHeaderAccessor) {        logger.error("handleInternal:errorHeaderAccessor-" + errorHeaderAccessor + ", errorPayload-" + errorPayload + ", error-" + cause.getMessage() + ", clientHeaderAccessor-" + clientHeaderAccessor);        return super.handleInternal(errorHeaderAccessor, errorPayload, cause, clientHeaderAccessor);    }

@RestControllerpublic class MessageController {    Logger logger = LoggerFactory.getLogger(MessageController.class);    @Autowired    private SimpMessagingTemplate messagingTemplate;    @RequestMapping("/api/h5/sendMsgBro")    @ResponseBody    public void sendMsg() {        logger.debug("服务器主动推送的广播消息");        messagingTemplate.convertAndSend("/topic/reloadpic", "服务器主动推送的广播消息");    }}
mounted: function () {
this.initWebSocket()
},
methods: {
initWebSocket: function () {
this.connection()
// 需要有一个失败重连得到问题
},
connection: function (count) {
let num=count||1;
const socket = new SockJS(`${base_url}/h5/endpointstore`)
this.stompClient = Stomp.over(socket)
//建立连接,订阅主题
this.stompClient.connect({}, (frame) => {
this.stompClient.subscribe('/topic/reloadpic', (val) => {
alert("重新加载图片")
window.location.reload(true);
})
},()=>
{
if (num < 10) {
console.log("重试链接次数:"+num);
setTimeout(() => {
this.connection(num + 1);
}, 10000 * num);
} else {
console.log("重试"+num+"此放弃重连了");
}
})
}}