0

我们想将第三方库(Eclipse XText LSP)集成到我们的 SpringBoot webapp 中。

该库与用户“交互”地工作(如聊天)。XText API 需要输入和输出流才能工作。我们希望使用 WebSocket 让用户与这个库顺利交互(发送/检索 json 消息)。

SpringBoot 存在问题,因为 SpringBoot 对 WebSocket 的支持不公开输入/输出流。我们编写了自定义 TextWebSocketHandler(子类),但没有一个方法提供对输入/输出流的访问。

我们还尝试了 HandshakeInterceptor (在握手后获取输入/输出流)但没有成功。

我们可以在这种情况下使用 SpringBoot WebSocket API 还是应该使用一些较低级别的(Servlet?)API?

问候丹尼尔

4

1 回答 1

1

我不确定这是否适合您的架构,但我通过使用 Spring Boot 的 STOMP 支持并将其连接到 customorg.eclipse.lsp4j.jsonrpc.RemoteEndpoint而不是使用较低级别的 API 来实现这一点。

该方法的灵感来自于通读org.eclipse.lsp4j.launch.LSPLauncher.

JSON 处理程序

编组和解组 JSON 需要使用 xtext 语言服务器提供的 API,而不是 Jackson(Spring STOMP 集成将使用)

Map<String, JsonRpcMethod> supportedMethods = new LinkedHashMap<String, JsonRpcMethod>();
supportedMethods.putAll(ServiceEndpoints.getSupportedMethods(LanguageClient.class));
supportedMethods.putAll(languageServer.supportedMethods());
jsonHandler = new MessageJsonHandler(supportedMethods);
jsonHandler.setMethodProvider(remoteEndpoint);

响应/通知

响应和通知由消息使用者发送,该消息使用者remoteEndpoint在构造时传递给该消息使用者。该消息必须由该消息进行编组,jsonHandler以防止杰克逊这样做。

remoteEndpoint = new RemoteEndpoint(new MessageConsumer() {
    @Override
    public void consume(Message message) { 
        simpMessagingTemplate.convertAndSendToUser('user', '/lang/message',
            jsonHandler.serialize(message));
    }
}, ServiceEndpoints.toEndpoint(languageServer));

要求

@MessageMapping可以使用一种将整体@Payload作为 a的方法来接收请求,String以避免 Jackson 解组它。然后,您可以解组自己并将消息传递给remoteEndpoint.

@MessageMapping("/lang/message")
public void incoming(@Payload String message) {
   remoteEndpoint.consume(jsonHandler.parseMessage(message));
}

可能有更好的方法来做到这一点,我会感兴趣地关注这个问题,但这是我发现的一种方法。

于 2018-06-18T09:35:00.350 回答