• 【遗留】等待谁来帮助一下,webSocket的messagingTemplate跨域问题


    未解决的webSocket问题

    背景

    首先为什么想用messagingTemplate,是因为这个是Spring的,而且这个竟然还能根据topic发送,就跟rabbitMQ一样,瞬间就觉得很亲切。但是但是,我发现了一个问题就是这家伙老是报跨域错误,如果你改成setAllowedOriginPatterns前端就会报403,我实在是解决不了这个问题。

    问题

    以前公司用的是messagingTemplate,下面这个代码是网上找到的,然后会报跨域问题

    package com.simple.ws.config;
    
    import com.simple.ws.constants.WsConstants;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.messaging.simp.config.MessageBrokerRegistry;
    import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
    import org.springframework.web.socket.config.annotation.*;
    
    /**
     * 

    * websocket核心配置类 *

    * * -- 说明:@EnableWebSocketMessageBroker作用 * 1)、注解用于开启使用stomp协议,来传输基于代理(MessageBroker)的消息,消息代理配置在下面; * 2)、开始支持@MessageMapping,类似于@requestMapping,这样就可以在controller接口中配合@SendTo注解来传输消息了。 */
    @Configuration @EnableWebSocketMessageBroker public class WebsocketConfig implements WebSocketMessageBrokerConfigurer { /** * 注册stomp端点 * -- 说明: * 1)、addEndpoint:端点,简单理解就是连接websocket的后缀地址; * 2)、addInterceptors:拦截器,一般用来进行客户端认证; * 3)、setAllowedOrigins:跨域授权,必须加的选项,否则服务内部之间通讯因为端口问题也会出现跨域问题; * 4)、withSockJS:指定使用SockJS,一般spring的项目都使用这个,因为默认就支持,而SockJS是前端主流用法,优势是兼容性好,客户端不支持ws会降级为长轮询。 * * @param registry stomp端点注册对象 */ @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint(WsConstants.WEBSOCKET_PATH) .setAllowedOrigins("*") .withSockJS(); } /** * 配置消息代理 * -- 说明: * 1)、这里注释掉调度器和心跳配置,只作为参考,后续完整项目会加上; * 2)、enableSimpleBroker:配置客户端能订阅的域,可以多个,简单讲就是配置了这些域,客户端必须以这些名称作为订阅地址,否则访问不到服务端, * 如果不配置,客户端随便自定义路径都行,只要服务端有对应的接口提供订阅即可,一般是必须要设置的,大部分人喜欢设置为广播/topic,点对点/queue; * 3)、setUserDestinationPrefix:设置点对点的订阅路径前缀,不设置的话默认是/user,设置的话比如/queue,那么客户端订阅时就必须以/queue开头,否则无法访问服务端; * 4)、setApplicationDestinationPrefixes:设置应用级的订阅路径前缀,比如设置为/app,那么客户端订阅时就必须以/app开头,否则访问不到服务端。 * * @param registry 消息代理注册对象 */ @Override public void configureMessageBroker(MessageBrokerRegistry registry) { // 自定义调度器,控制心跳线程数。 ThreadPoolTaskScheduler ts = new ThreadPoolTaskScheduler(); ts.setPoolSize(1); ts.setThreadNamePrefix("ws-heartbeat-thread-"); ts.initialize(); // 配置服务端推送消息给客户端的代理路径(客户端订阅的域),多个以逗号隔开。这里定义两个,点对点和广播代理。 registry.enableSimpleBroker(WsConstants.BROKER.BROKER_QUEUE, WsConstants.BROKER.BROKER_TOPIC) .setHeartbeatValue(new long[]{5000, 5000}) // 心跳5秒一次 .setTaskScheduler(ts); // 指定使用上面定义的调度器 // 定义点对点推送时的前缀为/queue,默认是/user。加了后默认值就会被覆盖。 registry.setUserDestinationPrefix(WsConstants.BROKER.BROKER_QUEUE); // 定义客户端访问服务端消息接口时的前缀,这里设为为/app, 默认是空字符串。加了之后前端访问接口就是stompClient.send("/app/send")。 registry.setApplicationDestinationPrefixes(WsConstants.WS_PERFIX); } }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    package com.simple.ws.controller;
    
    import com.simple.ws.constants.WsConstants;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.messaging.handler.annotation.MessageMapping;
    import org.springframework.messaging.simp.SimpMessagingTemplate;
    import org.springframework.web.bind.annotation.*;
    
    import java.util.Map;
    
    
    @RestController
    @RequestMapping("/api")
    @Slf4j
    public class MsgController {
    
    	private final SimpMessagingTemplate messagingTemplate;
    
    	public MsgController(SimpMessagingTemplate messagingTemplate) {
    		this.messagingTemplate = messagingTemplate;
    	}
    
    	/**
    	 * 发送广播消息
    	 * -- 说明:
    	 *       1)、@MessageMapping注解对应客户端的stomp.send('url');
    	 *       2)、用法一:要么配合@SendTo("转发的订阅路径"),去掉messagingTemplate,同时return msg来使用,return msg会去找@SendTo注解的路径;
    	 *       3)、用法二:要么设置成void,使用messagingTemplate来控制转发的订阅路径,且不能return msg,个人推荐这种。
    	 *
    	 * @param msg 消息
    	 */
    	@MessageMapping("/send")
    	public void sendAll(@RequestParam String msg) {
    
    		log.info("[发送消息]>>>> msg: {}", msg);
    
    		// 发送消息给客户端
    		messagingTemplate.convertAndSend(WsConstants.BROKER.BROKER_TOPIC, msg);
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    package com.simple.ws.constants;
    
    
    public class WsConstants {
    
    	// stomp端点地址
    	public static final String WEBSOCKET_PATH = "/websocket";
    
    	// websocket前缀
    	public static final String WS_PERFIX = "/app";
    
    	// 消息订阅地址常量
    	public static final class BROKER {
    		// 点对点消息代理地址
    		public static final String BROKER_QUEUE = "/queue/";
    		// 广播消息代理地址
    		public static final String BROKER_TOPIC = "/topic";
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    解决

    我最差的解决方法将版本降到2.4一下就能正常运行了,但是如果在企业中肯定不能将Spring-boot-starter的版本啊

        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.3.7.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
  • 相关阅读:
    2022-09-10 C++并发编程(二十一)
    useContext本身并不能直接向下传递方法,
    Java~List接口详解
    在数字化浪潮中,为企业建造一艘“方舟”
    2_dataset, dataloader
    可以提取图像文本的 5 大 Python 库
    代码整洁之道-读书笔记之格式
    RocketMQ详解(一):RocketMQ架构详解
    Wireshark抓包分析ICMP协议
    C++手敲Roberts_Prewitt_Sobel实现阈值分割
  • 原文地址:https://blog.csdn.net/weixin_43914278/article/details/134401464