当前位置: 首页 > 知识库问答 >
问题:

2种方式使用Spring webFlow流式传输

屠盛
2023-03-14

我想知道是否有可能实现2种方式的流式传输使用Spring WebFlow?基本上,我希望让客户端发送服务器接收到的数据通量将它们映射到String,然后返回结果,所有这些都流利地进行,而无需收集数据。我使用RSocket完成了它,但我想知道我是否可以使用超文本传输协议2.0(使用Spring和Project-Retor)获得相同的结果。

试过这样做:

1-客户:

  public Mono<Void> stream() {
    var input = Flux.range(1, 10).delayElements(Duration.ofMillis(500));
    return stockWebClient.post()
            .uri("/stream")
            .body(BodyInserters.fromPublisher(input, Integer.class))
            .accept(MediaType.TEXT_EVENT_STREAM)
            .retrieve()
            .bodyToFlux(String.class)
            .log()
            .then();
  }

2.服务器:

@PostMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
  public Flux<String> stream(@RequestBody Integer i) {
    return Flux.range(i, i+10).map(n -> String.valueOf(i)).log();
  }

或者:

public Flux<String> stream(@RequestBody Flux<Integer> i) {
    return i.map(n -> String.valueOf(i)).log();
  }

或者:

@PostMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
  public Flux<String> stream(@RequestBody List<Integer> i) {
    return Flux.fromIterable(i).map(n -> String.valueOf(i)).log();
  }

没有一个工作正常。

共有1个答案

杜浩壤
2023-03-14

如果你想使用服务器发送的事件,你需要返回一个Flux

所以你的服务器值应该是:

    @PostMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<ServerSentEvent<String>> stream(@RequestBody Integer i) {
        return Flux.range(i, i + 10).map(n -> ServerSentEvent.builder(String.valueOf(n)).build());
    }

但在这种情况下,主体只是一个整数,您的客户端代码变为:

input.flatMap(i ->
        stockWebClient
                .post()
                .uri("/stream")
                .bodyValue(i)
                .accept(MediaType.TEXT_EVENT_STREAM)
                .retrieve()
                .bodyToFlux(new ParameterizedTypeReference<ServerSentEvent<String>>() {})
                .mapNotNull(ServerSentEvent::data)
                .log())
                .blockLast();

您也可以对功能endpoint执行相同的操作。

如果您希望能够将数据从客户端流到服务器,然后再流到服务器,那么您将无法使用SSE,但您可以通过websocket实现这一点。

你需要一个HandlerMapping和一个WebSocketHandler

public class TestWebSocketHandler implements WebSocketHandler {
    @Override
    public Mono<Void> handle(WebSocketSession session) {
        Flux<WebSocketMessage> output = session.receive()
                .map(WebSocketMessage::getPayloadAsText)
                .map(Integer::parseInt)
                .concatMap(i -> Flux.range(i, i + 10).map(String::valueOf))
                .map(session::textMessage);
        return session.send(output);
    }
}

处理程序的配置:

@Bean
    public TestWebSocketHandler myHandler() {
        return new TestWebSocketHandler();
    }

    @Bean
    public HandlerMapping handlerMapping(final TestWebSocketHandler myHandler) {
        Map<String, WebSocketHandler> map = new HashMap<>();
        map.put("/streamSocket", myHandler);
        int order = -1; // before annotated controllers
        return new SimpleUrlHandlerMapping(map, order);
    }

在客户端:

var input2 = Flux.range(1, 10).delayElements(Duration.ofMillis(500));
        WebSocketClient client = new ReactorNettyWebSocketClient();
        client.execute(URI.create("http://localhost:8080/streamSocket"), session ->
                session.send(input2.map(i -> session.textMessage("" + i))).then(session.receive().map(WebSocketMessage::getPayloadAsText).log().then())
        ).block();

 类似资料:
  • 本文向大家介绍java JSONArray 遍历方式(2种),包括了java JSONArray 遍历方式(2种)的使用技巧和注意事项,需要的朋友参考一下 第一种(java8):遍历JSONArray 拼接字符串 第二种:for循环遍历 PS:遍历JsonObject 然后用Iterator迭代器遍历取值,建议用反射机制解析到封装好的对象中 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望

  • 问题内容: 我有一个200MB的文件,想通过下载提供给用户。但是,由于我们希望用户仅下载一次此文件,因此我们这样做: 强制下载。但是,这意味着整个文件必须加载到内存中,这通常不起作用。我们如何以每块kb的速度将文件流式传输给他们? 问题答案: 尝试这样的事情

  • 1.2. jQuery支持2种插件方式 $.somePlugin $.fn.somePlugin 1.2.1. Global工具类的插件 比如 $.trim('hello world ') 这个方法是用于去掉空格的工具方法。它其实是给jQuery对象上增加了trim方法。 此种插件一般是工具类的方法。 1.2.2. 基于selector的插件 比如 $('.mytab').tab({

  • 本文向大家介绍使用Vue实现图片上传的三种方式,包括了使用Vue实现图片上传的三种方式的使用技巧和注意事项,需要的朋友参考一下 项目中需要上传图片可谓是经常遇到的需求,本文将介绍 3 种不同的图片上传方式,在这总结分享一下,有什么建议或者意见,请大家踊跃提出来。 没有业务场景的功能都是耍流氓,那么我们先来模拟一个需要实现的业务场景。假设我们要做一个后台系统添加商品的页面,有一些商品名称、信息等字段

  • 本文向大家介绍javaScript使用EL表达式的几种方式,包括了javaScript使用EL表达式的几种方式的使用技巧和注意事项,需要的朋友参考一下 1.可以使用双引号将EL表达式括起来,这个不是对所有的都行,只对适合${param}这种类型 2.可以将其作为javaScript中的函数的参数。 3.使用隐藏表单域将值传过去原理和(1)是一样的!

  • 问题内容: 使用MVC模型,我想编写一个JsonResult,它将Json字符串流式传输到客户端,而不是一次将所有数据转换成Json字符串,然后将其流回客户端。我有一些动作需要在Json传输时发送非常大的记录(超过300,000条记录),我认为基本的JsonResult实现是不可伸缩的。 我正在使用Json.net,我想知道是否有一种方法可以在转换Json字符串时流化它的块。 但是我不确定如何将这