【遗留】等待谁来帮助一下,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); } }
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);
	}
}

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";
	}
}

解决

我最差的解决方法将版本降到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>

你可能感兴趣的:(websocket,网络协议,网络)