小编Mic*_*ler的帖子

Spring Boot Webflux/Netty - 检测关闭连接

我一直在2.0.0.RC1使用webflux starter(spring-boot-starter-webflux)开始使用spring-boot .我创建了一个简单的控制器,返回无限的通量.我希望发布者只有在有客户端(订阅者)时才能正常工作.假设我有一个像这样的控制器:

@RestController
public class Demo {

    @GetMapping(value = "/")
    public Flux<String> getEvents(){
        return Flux.create((FluxSink<String> sink) -> {

            while(!sink.isCancelled()){

                // TODO e.g. fetch data from somewhere

                sink.next("DATA");
            }
            sink.complete();
        }).doFinally(signal -> System.out.println("END"));
    }

}
Run Code Online (Sandbox Code Playgroud)

现在,当我尝试运行该代码并使用Chrome 访问端点http:// localhost:8080 /时,我可以看到数据.但是,一旦我关闭浏览器,while循环就会继续,因为没有触发取消事件.关闭浏览器后,如何终止/取消流媒体?

从这个答案我引用:

目前使用HTTP,确切的背压信息不会通过网络传输,因为HTTP协议不支持此功能.如果我们使用不同的线路协议,这可能会改变.

我认为,由于HTTP协议不支持背压,这意味着也不会发出取消请求.

通过分析网络流量进一步调查,显示浏览器在FIN关闭浏览器后立即发送TCP .有没有办法配置Netty(或其他),以便半封闭连接将触发发布者的取消事件,使while循环停止?

或者我是否必须编写自己的适配器,类似于org.springframework.http.server.reactive.ServletHttpHandlerAdapter我实现自己的订阅服务器的地方?

谢谢你的帮助.

编辑: 一个IOException将在尝试,如果没有客户端将数据写入套接字提高.正如您在堆栈跟踪中看到的那样.

但这还不够好,因为在下一个数据块准备好发送之前可能需要一段时间,因此需要花费相同的时间来检测已经消失的客户端.正如Brian Clozel所说,它是Reactor Netty中的一个已知问题.我试图通过添加依赖项来使用Tomcat POM.xml.像这样:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
Run Code Online (Sandbox Code Playgroud)

虽然它取代了Netty并使用了Tomcat,但由于浏览器没有显示任何数据,它似乎没有被动反应.但是,控制台中没有警告/信息/异常.spring-boot-starter-webflux这个版本( …

spring spring-boot project-reactor reactive-streams spring-webflux

6
推荐指数
1
解决办法
3984
查看次数