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

当客户端与热流断开连接时执行一些操作

华景同
2023-03-14

我制作了一个简单的spring boot应用程序。我有一个RESTendpoint,它返回当前时间的热流。

@RestController
public class NowResource {

    @GetMapping(value = "/now", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> now() {
        return Flux.interval(Duration.ofSeconds(1))
            .flatMap(t -> Flux.just(Instant.now().toString()));
    }

}

当我调用http://localhost:8080/now时,我得到的数据流看起来像:

数据:2018-04-03T13:20:38.31322100Z

数据:2018-04-03T13:20:39.31149350Z

Data: 2018-04-03T13:20:40.310878800Z

......

当我断开与流的连接(关闭浏览器选项卡)时,会抛出并捕获IOException,并打印堆栈跟踪。

JAVA伊奥。IOException:主机中的软件中止了已建立的连接

......

我试过抓住它,但它已经被抓住了,不能回到我的方法。

我尝试添加doOnTerminate()doOnError()等到Flux,但似乎没有任何效果,我猜实际事件是不同类型的。

我能以某种方式访问这个异常,以不同于打印它的方式处理它吗?(我想避免日志中有200行输出,而只打印“完成”。)

编辑:我的解决方案基于托马斯·皮诺斯的答案

我最终采用了这种方法,不同之处在于我将其移动到了一个新类中,这样它就可以处理来自所有控制器的所有此类异常。

@Slf4j
@ControllerAdvice
class IOExceptionHandler implements WebExceptionHandler {

    @ExceptionHandler(IOException.class)
    public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
        return Mono.just(ex.getMessage())
            .doOnNext(
                msg -> log.warn("IOException occurred: {}.", msg)
            )
            .then();
    }

}

共有1个答案

谭裕
2023-03-14

该异常与浏览器和控制器之间的HTTP连接处理有关(简单地说)。

它可以在控制器的@ExceptionHandler方法中处理(或者在@ControllerAdvice类中处理,如果您想在更多控制器上应用相同的异常处理)。

例如:

@RestController
public class NowResource {
    ...

    @ExceptionHandler(IOException.class)
    public void handleException(IOException e) {
        log.warn("IOException occurred: {}", e.getMessage());
    }
}
 类似资料:
  • null 当MQTT代理变得不可用时,Paho MQTT客户机不能帮助我保证这些QoS2级别的消息将被重新传递,这是正确的说法吗? 因此,我如何区分以下情况,即Client.Publish导致了一个MqttException,其中Paho没有将消息持久化。 下面是它在飞行中坚持的地方 null 连接丢失(32109):PAHO保存消息 客户端当前正在断开连接(32102):PAHO丢失消息 等待服

  • 当我再次调用时,第二次调用将按预期返回。但我想明白,为什么第一次打电话成功了?我是否遗漏了某些特定于TCP的细节?这种奇怪的(对我来说)行为只针对{活动,错误}连接。

  • 我正在使用C#window应用程序表单对TCP多线程服务器进行工作,我正在尝试检测客户端的机器是否关闭并断开与服务器的连接。看了一些帖子,有了一些想法: 如何确定tcp是否连接? 我的代码如下: 多谢帮忙。

  • 我使用java ssh客户端(http://www.jcraft.com/jsch/)连接到远程机器并执行命令。代码工作正常,直到我连接到远程机器并执行命令。然而,问题是,即使命令执行成功,通道和会话也不会断开。 我也打电话给session.disconnect和channel.disconnect,但仍然是问题所在。 这是我的代码: 请建议

  • 我正在用Java编写一个简单的TCP客户机/服务器程序对,如果客户机在10秒内还没有发送任何东西,服务器必须断开连接。socket.setsoTimeout()使我得到了这一点,服务器就可以很好地断开连接。问题是--我如何让客户端确定服务器是否关闭?目前,我使用DataOutputStream向服务器写入数据,这里的一些答案表明,向封闭套接字写入数据将引发IOException,但这不会发生。 编

  • 问题内容: 我使用和创建一个实时Web应用程序。我将为用户提供对套接字连接的完全控制,例如手动断开连接和(重新)连接。 在客户端启动时,该功能可以正常运行,但是在使用之后,不会启动新连接。 问题答案: 现在可以使用socket.socket.reconnect() 相关:https : //github.com/LearnBoost/socket.io- client/issues/251