springboot成神之——websocket发送和请求消息

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

    • 项目目录
    • 依赖
    • DemoApplication
    • MessageModel
    • WebConfig
    • WebSocketConfig
    • HttpHandshakeInterceptor
    • WebSocketEventListener
    • WebSocketController
    • 前端测试

本文介绍如何使用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/[email protected]/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/[email protected]/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>

原文地址:https://www.cnblogs.com/ye-hcj/p/9640436.html

时间: 2024-08-29 15:07:34

springboot成神之——websocket发送和请求消息的相关文章

springboot成神之——监视器

Spring Boot 的监视器 依赖 配置 书写监视控制器 常用的一些内置endpoint 定义actuator/info特殊endpoint actuator/shutdown需要post请求才能访问 Spring Boot 的监视器 此功能用来控制spring boot程序和查看程序信息 依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot

springboot成神之——拦截器

本文介绍spring boot拦截器 创建拦截器类LogInterceptor.java 创建拦截器类OldLoginInterceptor.java 拦截器配置类WebMvcConfig.java 路由InterceptorController.java 本文介绍spring boot拦截器 创建拦截器类LogInterceptor.java package com.springlearn.learn.interceptor; import javax.servlet.http.HttpSer

springboot成神之——RestTemplate访问Rest

本文介绍RestTemplate访问Rest demo package com.springlearn.learn; import java.util.Arrays; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.http.HttpEntity; im

springboot发送http请求

springboot中实现http请求调用api 创建发送http请求service层 import org.springframework.http.*; import org.springframework.stereotype.Service; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; /**  * @Author 冯战魁  * @Da

前端性能优化成神之路-总结

首先来看一下前端性能优化所涉及的层面有如下四个:网络层面,构建层面,浏览器渲染层面,服务端层面 具体的优化点有:资源合并与压缩,图片编码原理和类型的选择,浏览器的渲染机制,懒加载与预加载,浏览器存储,缓存机制,PWA,Vue-SSR等等 首先来了解一下web前端的本质 web前端的本质是一种GUI软件,是可以直接借鉴其他GUI系统架构设计的方法,但是web前端有点特别 下面是CS架构的GUI软件的开发和部署过程,CS架构的GUI软件在用户从商店下载下来后,是一个APK包,通过解压安装到手机的操作

解决浏览器跨域限制发送ajax请求

一.什么是浏览器跨域限制?本质是什么? 所谓浏览器跨域限制,其实是为了数据安全的考虑由Netscape提出来限制浏览器跨域访问数据的策略,这是一中约定,正式叫法为浏览器同源策略,目前已经在大多数浏览器中支持. 本质上,所谓浏览器同源策略即:不允许浏览器访问跨域的Cookie,ajax请求跨域接口等.也就是说,凡是访问与自己不在相同域的数据或接口时,浏览器都是不允许的. 最常见的例子:对于前后端完全分离的Web项目,前端页面通过rest接口访问数据时,会出现如下问题: 不允许发送POST请求:在发

GET 和 POST的区别? 用POST方法发送登陆请求

GET 和 POST的区别? 用POST方法发送登陆请求. { <1> http方法: http协议定义了很多方法对应不同的资源操作,其中最常用的是GET 和 POST 方法. { { GET.POST.OPTIONS.HEAD.PUT.DELETE.TRACE.CONNECT.PATCH } 增:PUT 删:DELETE 改:POST 查:GET } <2> 参数 { 因为 GET 和 POST 可以实现上述所有操作,所以,在现实开发中,我们只要会用GET 和 POST 方法就可

c#代码,模拟form表单发送post请求,上传文件(并带其他参数)

本人对post理解不深,前段时间遇到一个需要用c#代码发送post请求上传文件的业务,于是参考了几篇帖子,加上自身实践写出了如下代码.写的比较low 望各位大大指正^_^. 业务需求: 对方给了一个接口,让传四个参数分别为"modelId.fileContent.updateTime.encrypt" 其中modelId.updateTime.encrypt 都是普通的字符串类型.fileContent则是二进制文件 我实在是不了解post的相关知识,平时只是普通的用法,没有深层看过相

通过在jquery中添加函数发送ajax请求来加载数据库数据,以json的格式发送到页面

通过在jquery中添加函数发送ajax请求来加载数据库数据,以json的格式发送到页面 从数据库中查询仓库信息,显示在下拉菜单中: 首先,引入js插件,这里使用jquery-1.8.3.js <script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery-1.8.3.js"></script> 当页面加载完成后,就应该发送ajax请求到数据库,