react-spring 如何用旁路设计赋能前端交互

本文探讨了在web terminal需求中如何利用react-spring和websocket进行前后端通讯。详细介绍了SimpMessagingTemplate的作用,包括在任意位置发送消息和为特定用户发送消息。并解析了使用SimpMessagingTemplate发送websocket消息给客户端的步骤,以及解决由此引发的循环依赖问题。最后,提到了关于JavaScript与ES的笔记资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在做一个web terminal的需求,自己也写了 demo ,使用 websocket + stomp 进行前后端通讯,其中遇到一个问题,就是我的前后端连接正常及 ssh 连接也正常了,但是我需要把 ssh 连接返回的信息,再返回给客户端。了解到使用 SimpMessagingTemplate ,但是在使用过程中却遇到一个循环依赖的问题,所以这里记录一下。

SimpMessagingTemplate的作用

1、SimpMessagingTemplate可以在应用的任意地方发送消息。

Spring的SimpMessagingTemplate能够在应用的任何地方发送消息,甚至不必以首先接收一条消息作为前提。 使用SimpMessagingTemplate的最简单方式是将它(或者其接口SimpMessageSendingOperations)自动装配到所需的对象中。

2、SimpMessagingTemplate可以为指定的用户发送消息。

SimpMessagingTemplate还提供了convertAndSendToUser()方法。convertAndSendToUser()方法能够让我们给特定用户发送消息。

simpMessageSendingOperations.convertAndSendToUser("1", "/message", "测试convertAndSendToUser");

stomp.subscribe('/users/1/message', function(message){ }); 

客户端接收一对一消息的主题是"/users/“+usersId+”/message",这里的用户Id可以是一个普通字符串,只要每个客户端都使用自己的Id并且服务器端知道每个用户的Id就行了。

如何使用SimpMessagingTemplate将websocket消息发送给客户端

1、引入 websocket 依赖

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

2、配置registry注册点

@Configuration
@Slf4j
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {@Overridepublic void registerStompEndpoints(StompEndpointRegistry registry ) {//路径"/web-terminal"被注册为STOMP端点,对外暴露,客户端通过该路径接入WebSocket服务registry.addEndpoint("web-terminal").setAllowedOrigins("*");}@Overridepublic void configureMessageBroker(MessageBrokerRegistry config) {// 用户可以订阅来自以"/topic"为前缀的消息,客户端只可以订阅这个前缀的主题config.enableSimpleBroker("/topic/1024");// 客户端发送过来的消息,需要以"/xterm"为前缀,再经过Broker转发给响应的Controllerconfig.setApplicationDestinationPrefixes("/xterm");}
} 

3、使用SimpMessagingTemplate将websocket消息发送给客户端

// 1、注入SimpMessagingTemplate 调用convertAndSend来推送消息
@Autowired
private SimpMessagingTemplate simpMessagingTemplate;

// 2、使用
while ((i = inputStream.read(buffer)) != -1) {System.out.println(new java.lang.String(Arrays.copyOfRange(buffer, 0, i)));template.convertAndSend("/topic/1024", new String(Arrays.copyOfRange(buffer, 0 , i)));
} 

解决SimpMessagingTemplate循环依赖问题

1、问题背景

在这个类上注入 SocketService,SocketService 里有我们的业务处理,在 SocketService 里我们需要将消息发送给客户端,所以需要注入 SimpMessagingTemplate, 但是一运行就会报错 循环依赖 的问题。

猜测可能是 WebSocketConfig 实现的 WebSocketMessageBrokerConfigurer 里有实现 SimpMessagingTemplate,那么 WebSocketConfig 依赖 SocketService,反过来 SocketService 又依赖 SimpMessagingTemplate,所以导致了循环依赖问题。

2、解决方案

根据 spring 的描述,基于构造器的循环依赖是没法解决的,官方文档都摊牌了,你想让构造器注入支持循环依赖,是不存在的,不如把代码改了。所以解决方法就是可以改造一下代码。

在 Controller 层去注入 SimpMessagingTemplate,然后将其作为参数传给 Service层的 SocketService 里的方法去调用。

// Controller 层注入及传参
@Controller
@AllArgsConstructor
public class SocketController {private SocketService socketService;private SimpMessagingTemplate template;@MessageMapping("/msg")public void send(WebSSHData webSSHData) {System.out.println(webSSHData.getOperate());socketService.handlerMsg(webSSHData, template);}
}

// Service 层拿到参数去处理
public void handlerMsg(WebSSHData webSSHData, SimpMessagingTemplate template) {......connectToSSH(sshConnectInfo, finalWebSSHData, template);
}

// 在 connectToSSH 里使用
template.convertAndSend("/topic/1024", new String(Arrays.copyOfRange(buffer, 0, i))); 

这样确实就解决了循环依赖的问题,消息也顺利的发送给了客户端。

最后

最近还整理一份JavaScript与ES的笔记,一共25个重要的知识点,对每个知识点都进行了讲解和分析。能帮你快速掌握JavaScript与ES的相关知识,提升工作效率。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值