即使网络中断,如何继续在 websockets 中发送消息?

Posted

技术标签:

【中文标题】即使网络中断,如何继续在 websockets 中发送消息?【英文标题】:How to keep sending messages in websockets even when the network is down? 【发布时间】:2016-11-04 06:29:06 【问题描述】:

我正在使用 websockets(org.java_websocket) 的 java 实现。我正在使用“ifconfig l0 down”来模拟网络故障。我希望服务器即使在网络关闭时也能继续发送消息,并在网络再次启动时重新发送它们(通过 tcp 机制)。但是,java实现在send函数中有如下检查

private void send( Collection<Framedata> frames ) 
    if( !isOpen() )
        throw new WebsocketNotConnectedException();

导致

an error occured
close a stream
Exception in thread "main" org.java_websocket.exceptions.WebsocketNotConnectedException

一旦我模拟服务器和客户端之间的连接丢失。

由于我没有正确调用 websockets 中的 close() 函数,我觉得 TCP 机制应该工作一段时间,然后超时导致 websockets 层关闭连接。我期待一些外在的东西吗?有没有可以帮助我的实现?

【问题讨论】:

我正在使用github.com/TooTallNate/Java-WebSocket 这里的问题不是网络问题,而是你的代码在某个地方关闭了套接字,然后继续使用它。 @EJP 虽然,我解决了这个问题,你能帮我解决***.com/questions/40441420/… 上发布的后续问题吗? 【参考方案1】:

通过ifconfig down模拟网络连接问题不是一个好主意,因为操作系统知道接口状态。然后,操作系统可能(并且确实)以不同方式处理连接错误和接口错误,并且网络应用程序会收到不同的错误指示。

如何在 linux 机器上模拟连接错误的选项是iptables。假设您的应用程序使用端口 80。您可以通过

删除与端口 80 之间的所有通信
iptables -A INPUT -p tcp --destination-port 80 -j DROP
iptables -A OUTPUT -p tcp --source-port 80 -j DROP

iptables 中的流量下降就像网络中断一样处理。

【讨论】:

您好,感谢您的回复。是的,我就是这么做的。我使用了 iptables 的等价物,它是 mac 的 pfctl。现在我已经这样做了,在开启和关闭期间的几次迭代中一切正常,但随后突然流关闭并且在关闭期间开始时打开防火墙时连接中断。 我找出了网络出现故障的原因,并将其作为一个新问题发布在***.com/questions/40441420/…。如果您能提供帮助会很高兴。【参考方案2】:

我认为您在这里的测试设置并没有真正做到您想要的。我猜发生的情况是,一旦您使用ifconfig,操作系统就足够智能,可以查找哪些套接字绑定到该接口并关闭它们。因此,Java 和 websocket 应用程序会收到有关已关闭套接字的通知,并且 websocket 连接会被清理。

您可能需要另一种方法来模拟“拔出”连接,因为您希望看到高丢包率/延迟但没有实际的连接关闭通知。

【讨论】:

您好,感谢您的回复。是的,我就是这么做的。我使用了另一个答案中提到的 iptables 的等价物,即 pfctl for mac。现在我已经这样做了,在开启和关闭期间的几次迭代中一切正常,但突然流关闭并且在关闭期间开始时打开防火墙时连接中断。 我找出了网络中断的原因,并将其作为一个新问题发布在***.com/questions/40441420/…。如果您能提供帮助会很高兴。【参考方案3】:

回答这个问题已经太晚了,但我认为我的回答可以帮助其他人: 你应该使用

connectBlocking() 

而不是

connect()

功能。注意 connectBlocking() ,阻塞你的线程!

【讨论】:

以上是关于即使网络中断,如何继续在 websockets 中发送消息?的主要内容,如果未能解决你的问题,请参考以下文章

websocket.close() 函数继续运行后

如何从另一个线程中断 websocket(使用 boost beast)?

如何在方法中返回中断或继续是不是可能?

即使录制意外中断(例如电源断开),如何在 gstreamer 中录制可播放的视频文件?

一文梳理HTTP、TCP、Socket和WebSocket的区别和联系

HTTP、TCP、Socket和WebSocket的区别和联系