gpt4 book ai didi

java - 有没有办法获得从客户端浏览器到模拟 shell 的服务器应用程序的双向连接?

转载 作者:行者123 更新时间:2023-11-28 23:11:41 26 4
gpt4 key购买 nike

问题

非常简短:我想创建 Spring Shell,但作为 Web 应用程序。

我想创建一个 Web 应用程序(最好使用 Spring Boot),其中前端 (ReactJS) 看起来像一个终端(或 shell),后端处理输入的命令。看https://codepen.io/AndrewBarfield/pen/qEqWMq .我想为看起来像那样的东西构建一个完整的网络应用程序。

我想构建一个框架,这样我就可以在对前端/Web 应用程序结构一无所知的情况下开发后端命令。我基本上想实例化一个“终端”对象,我在其中提供某种输入流和输出流。这样我就可以根据我给定的接口(interface)和结构对该终端进行编程,而无需设置各种前端内容。

问题的一个很好的总结是:如何将所有键盘输入发送到后端,以及如何将所有输出发送到前端?

我想创建一个 Web 应用程序的原因是因为我希望它可以在线使用。

我尝试过的

我认为实现这一点的方法是使用 websockets。我使用此 ( https://developer.okta.com/blog/2018/09/25/spring-webflux-websockets-react) 教程创建了一个小型 Web 应用程序,没有安全部分。 websocket 部分几乎是合适的,我就是无法获得“输入”和“输出”流式对象。

@Controller
public class WebSocketController {

private SimpMessagingTemplate simpMessagingTemplate;

@Autowired
public WebSocketController(SimpMessagingTemplate simpMessagingTemplate) {
this.simpMessagingTemplate = simpMessagingTemplate;
}

@MessageMapping("/queue")
@SendToUser("/topic/greetings")
public Greeting greeting(HelloMessage message, @Header(name = "simpSessionId") String sessionId) throws Exception {
System.out.println(sessionId);

// Do some command parsing or whatever.
String output = "You inputted:" + HtmlUtils.htmlEscape(message.getName());

return new Greeting(output);
}

private MessageHeaders createHeaders(String sessionId) {
SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor.create(SimpMessageType.MESSAGE);
headerAccessor.setSessionId(sessionId);
return headerAccessor.getMessageHeaders();
}

现在有了这段代码,您就可以解析命令了。但是,它不保留任何“状态”。我不知道它如何与状态和 websockets 一起工作。

我看到你有这个 Spring Sessions + WebSockets ( https://docs.spring.io/spring-session/docs/current/reference/html5/guides/boot-websocket.html ),但这并不是我真正想要的。

我可以使用以下代码从后端向前端发送消息:

simpMessagingTemplate.convertAndSendToUser(sessionId, "/topic/greetings", "hey", createHeaders(sessionId));

但是,我希望我的终端能够等待来自用户的输入命令。看起来有点牵强,但有人知道如何实现吗?

我想要的东西

我基本上希望其他人对这个接口(interface)进行编程:

public interface ITerminal {
void setInputStream(Object someKindOfWrapperForTheInput);
void setOutputStream(Object someWrapperOfSimpMessagingTemplate);
void start();
}

当有人打开 Web 应用程序时,他们会得到一个专用的终端对象(因此每个用户一个连接)。无论何时有人在前端应用程序中输入命令,我都希望它被终端对象接收、处理,并将响应输出到前端。

这样做的原因

我真的很喜欢创建命令行应用程序,但我不喜欢构建前端的东西。我在一家构建 Web 应用程序的公司担任软件工程师,我主要负责编写后端程序。所有前端部分都是由其他人完成的(我很幸运!)。不过,我喜欢在家做一些项目,这看起来很酷。

如果您对如何解决这个问题有任何想法或想法,请给出答案!我对解决方案很感兴趣,使用 SpringBoot 框架不是必需的。我使用 Spring Boot 和 ReactJS 问这个问题,因为我已经用它构建了应用程序。已经弄清楚了很多,我认为这可能也存在。唯一的要求是我可以在 tomcat 服务器上使用 Java 实现这一点。其余的是可选的:)

不清楚?

我尽力使我的故事清晰,但我不确定我想要实现的目的是否明确。但是,我不知道如何以您理解的方式来表述它。如果您有任何建议或问题,请随时发表评论!

最佳答案

如果您唯一想要的是一个在浏览器中显示的 Live Spring shell,那非常简单,您只需通过 WebSocketConfigurer 公开一个标准的 WebSocket,然后添加一个 WebSocketHandler 执行命令,然后将结果字符串作为 TextMessage 返回。

首先是允许客户端连接到“cli”端点的套接字配置

@Configuration
@EnableWebSocket
public class WebSocketConfiguration implements WebSocketConfigurer {

@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(cliHandler(), "/cli").setAllowedOrigins("*");
}

@Bean
public CLIWebSocketHandler cliHandler() {
return new CLIWebSocketHandler();
}
}

然后是执行命令的WebSocketHandler。我建议您将返回类型指定为 String 的每个 @ShellMethod,不要使用日志记录或系统写入,因为它们不会在评估期间返回。

@Component
public class CLIWebSocketHandler extends TextWebSocketHandler {

@Autowired
private Shell shell;

@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
String result = shell.evaluate(() -> message.getPayload()).toString();

session.sendMessage(new TextMessage(result));
}
}

您可以使用像 Simple WebSocket Client 这样的扩展名要对其进行测试,请转至 ws://localhost:port/cli

这是最基本的解决方案,在此之后添加安全性等功能应该很容易。请注意,我没有使用 STOMP,因为您可能想要隔离用户。但它可以与基于 STOMP 的端点一起工作,因此您可以为项目的其他部分提供发布-订阅功能。

从这个问题来看,我觉得您想要的答案涉及输入和输出流。您可能会考虑将 Spring Shell 的输出重定向到不同的流,然后将它们转发到 session ,但它可能要复杂得多并且有其他权衡。只返回一个字符串作为结果更简单,无论如何它在打印输出中看起来更好。

关于java - 有没有办法获得从客户端浏览器到模拟 shell 的服务器应用程序的双向连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57135669/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com