zoukankan      html  css  js  c++  java
  • springboot成神之——websocket发送和请求消息

    本文介绍如何使用websocket发送和请求消息

    项目目录

    依赖

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

    DemoApplication

    package com.springlearn.learn;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class DemoApplication {
    
    	public static void main(String[] args) {
    		SpringApplication.run(DemoApplication.class, args);
    	}
    }
    

    MessageModel

    package com.springlearn.learn.model;
    
    public class MessageModel {
    
        private String name;
    
        public String getName() {
            return "测试成功" + name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    

    WebConfig

    package com.springlearn.learn.config;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.annotation.EnableScheduling;
    import org.springframework.web.servlet.config.annotation.CorsRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    @Configuration
    @EnableScheduling
    public class WebConfig implements WebMvcConfigurer {
    
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**").allowedOrigins("*").allowedMethods("GET", "POST", "PUT", "DELETE").allowedOrigins("*")
            .allowedHeaders("*");
        }
    }
    

    WebSocketConfig

    package com.springlearn.learn.config;
    
    import com.springlearn.learn.Handler.HttpHandshakeInterceptor;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.messaging.simp.config.MessageBrokerRegistry;
    import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
    import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
    import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
    
    @Configuration
    @EnableWebSocketMessageBroker
    public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
         
        @Autowired
        private HttpHandshakeInterceptor handshakeInterceptor; // 这个是自定义的拦截器
     
        @Override
        public void registerStompEndpoints(StompEndpointRegistry registry) {
            registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS().setInterceptors(handshakeInterceptor);
        }
     
        @Override
        public void configureMessageBroker(MessageBrokerRegistry registry) {
            registry.setApplicationDestinationPrefixes("/app"); // 前端发送消息的前缀
            registry.enableSimpleBroker("/topic"); // 前端接收后台消息和后台发送消息给前端的前缀
        }
     
    }
    

    HttpHandshakeInterceptor

    package com.springlearn.learn.Handler;
    
    import java.util.Map;
    
    import javax.servlet.http.HttpSession;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.http.server.ServerHttpRequest;
    import org.springframework.http.server.ServerHttpResponse;
    import org.springframework.http.server.ServletServerHttpRequest;
    import org.springframework.stereotype.Component;
    import org.springframework.web.socket.WebSocketHandler;
    import org.springframework.web.socket.server.HandshakeInterceptor;
    
    @Component
    public class HttpHandshakeInterceptor implements HandshakeInterceptor {
     
        private static final Logger logger = LoggerFactory.getLogger(HttpHandshakeInterceptor.class);
         
        @Override
        public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
             
            logger.info("Call beforeHandshake"); // 和out一样,输出语句,正式开发用这个多
             
            if (request instanceof ServletServerHttpRequest) {
                ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
                HttpSession session = servletRequest.getServletRequest().getSession();
                attributes.put("sessionId", session.getId());
            }
    
            return true;
        }
     
        public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
                Exception ex) {
            logger.info("Call afterHandshake");
        }
         
    }
    

    WebSocketEventListener

    // 监听器,监听socket连接和短线
    package com.springlearn.learn.listener;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.event.EventListener;
    import org.springframework.messaging.simp.SimpMessageSendingOperations;
    import org.springframework.messaging.simp.stomp.StompHeaderAccessor;
    import org.springframework.stereotype.Component;
    import org.springframework.web.socket.messaging.SessionConnectedEvent;
    import org.springframework.web.socket.messaging.SessionDisconnectEvent;
    
    @Component
    public class WebSocketEventListener {
     
        private static final Logger logger = LoggerFactory.getLogger(WebSocketEventListener.class);
     
        @Autowired
        private SimpMessageSendingOperations messagingTemplate;
     
        @EventListener
        public void handleWebSocketConnectListener(SessionConnectedEvent event) {
            logger.info("Received a new web socket connection");
        }
     
        @EventListener
        public void handleWebSocketDisconnectListener(SessionDisconnectEvent event) {
            StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(event.getMessage());
     
            String username = (String) headerAccessor.getSessionAttributes().get("username");
             
            if(username != null) {
                logger.info("User Disconnected : " + username);
                messagingTemplate.convertAndSend("/topic/getResponse", "User Disconnected : " + username);
            }
        }
         
    }
    

    WebSocketController

    package com.springlearn.learn.controller;
    
    import java.text.DateFormat;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import com.springlearn.learn.model.MessageModel;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.messaging.handler.annotation.MessageMapping;
    import org.springframework.messaging.handler.annotation.Payload;
    import org.springframework.messaging.handler.annotation.SendTo;
    import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
    import org.springframework.messaging.simp.SimpMessageSendingOperations;
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Controller;
    
    
    @Controller
    public class WebSocketController {
    
        private static final DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss sss");
    
        @Autowired
        private SimpMessageSendingOperations messagingTemplate;
    
        @MessageMapping("/welcome")
        @SendTo("/topic/getResponse")
        public MessageModel sendMessage(@Payload MessageModel requestMessage, SimpMessageHeaderAccessor headerAccessor) {
            headerAccessor.getSessionAttributes().put("username", requestMessage.getName());
            MessageModel message = new MessageModel();
            message.setName(requestMessage.getName());
            return message;
        }
    
        @Scheduled(cron="* * * * * *" )
        @SendTo("/topic/getResponse")
        public Object callback() throws Exception {
            Date now = new Date();
            messagingTemplate.convertAndSend("/topic/getResponse", df.format(now));
            return "callback";
        }
    }
    

    前端测试

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
        <link rel="stylesheet" href="//unpkg.com/iview/dist/styles/iview.css">
        <script src="//unpkg.com/iview/dist/iview.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script>
        <script  src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js"></script>
    </head>
    <body>
        <div id="app">
        </div>
        <script>
            new Vue({
                el: '#app',
                mounted () {
                    
                    var stompClient = null;
    
                    var socket = new SockJS('http://localhost:9001/ws');
                    stompClient = Stomp.over(socket);
                    stompClient.connect(
                        {}, 
                        function (frame) {
                            stompClient.subscribe('/topic/getResponse', function (payload) {
                                console.log(payload.body)
                            })
    
                            stompClient.send(
                                "/app/welcome",
                                {},
                                JSON.stringify({name: "yejiawei"})
                            )
                        }, 
                        function(error) {
                            connectingElement.textContent = 'Could not connect to WebSocket server. Please refresh this page to try again!';
                            connectingElement.style.color = 'red';
                        }
                    );
    
                    setTimeout(function() {
                        stompClient.send(
                            "/app/welcome",
                            {},
                            JSON.stringify({name: "来自前端的请求"})
                        )
                    }, 3000)
                }
                
            })
        </script>
    </body>
    </html>
    
  • 相关阅读:
    linux环境下安装nginx步骤
    时间戳—时间互转 java
    redis配置中踩过的坑
    在Windows端安装kafka 提示错误: 找不到或无法加载主类 的解决方案
    Windows平台kafka环境的搭建
    在windows上搭建redis集群(redis-cluster)
    身份证号打码隐藏
    PIL获取图片亮度值的五种方式
    Python文件排序
    PIL
  • 原文地址:https://www.cnblogs.com/ye-hcj/p/9640436.html
Copyright © 2011-2022 走看看