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

/**
 * <p>
 * websocket核心配置类
 * </p>
 *
 * -- 说明:@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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值