我有两个应用程序通过
NamedPipes
相互通信。我们称它们为 appServer
(服务器)和 appClient
(客户端)。他们成功连接并在一段时间内来回发送数据。然后,出乎意料的是,appClient
崩溃了。用户重新启动它并尝试连接到管道,但appServer
仍然认为它已连接,因此没有侦听新连接。
我目前在服务器端使用
NamedPipeServerStream
(将 .IsConnected
返回为 true
,在客户端使用 NamedPipeClientStream
(将 .IsConnected
返回为 false
)。
我的问题是:我可以以某种方式让客户端能够重新连接吗?我显然已经尝试过
.Connect
有或没有超时,但没有运气。
如有任何提示,我们将不胜感激! 谢谢!
编辑: 另一个有效的(尽管不可取)选项是在服务器端执行一些廉价的操作,基本上进行“连接测试”,以确保客户端“仍然存在”。有人知道其中之一吗?除了发送虚拟消息之外,我不确定执行此操作的最佳方法。我不喜欢这个选择,因为它必须不断发生,但我对所有途径持开放态度,对喵。
我们的解决方案最终是启动第二个线程来等待另一个连接。然后我们比较客户端,如果是同一个客户端,那么我们关闭并回收原始服务器管道以保持其清洁。
不幸的是,NamedPipeServerStream 不会检测到连接已关闭,直到您尝试使用它发送内容。
最简单的解决方法是定期发送一条短消息,例如特定字节,并对客户端进行编程以忽略它们。
或者,您可以简单地定期关闭并重新打开双方的连接,这会使用一些资源,但根据您的逻辑可能更容易实现。
我的测试表明这种情况会在非常特殊的情况下发生。所有各种 Connect 和 ConnectAsync 重载的文档都明确指出:
连接到等待的服务器
只要服务器首先启动,并且实际上正在等待,它就会按照文档运行。当然,很多时候,由于人为因素或其他限制,保证服务器首先启动并不总是一种选择。因此,如果客户端调用 Connect() 或等待 ConnectAsync() 且没有超时,则当服务器启动时,它将看到客户端连接(但客户端不会确认),然后开始尝试读取。
但是,客户端不会识别该连接,也不会进入读取循环,并且不会为 IsConnected 返回 true。相反,它只会坐在那里等待连接。即使您提供连接超时并重试连接,服务器仍然高兴地坐在那里等待它永远不会得到的读取,并且在这种特定情况下,是的,上述两种方法中的任何一种都应该可以正常工作。我选择了定时器上的“保持活动”发送。感觉又脏又乱,但它确实有效。
因此,有时需要解决方法,例如解决特定用例的解决方法。理想情况下:
1:保证服务器在客户端调用 Connect 或 ConnectAsync 之前处于“等待”状态。这是理想的。在这种情况下,当管道损坏时,NamedPipeServerStream 将抛出记录的异常。
2:使用建议的其他两种方法之一(保活工作正常,我已经尝试过,感觉很脏,但有效)或当同一客户端连接时使用备用线程。这对我来说感觉很奇怪,因为在某些情况下,您需要向服务器发送一些指示客户端是什么的信息。
3:我将尝试一些新的东西,我认为这对我们来说会很有效:
因此,它不再是持久的保持活动状态,而是更像是一次性的“Are-you-alive”消息。一旦设置完毕,我们就已经有大量数据通过管道传输,以了解在初始启动协商后两端是否存在问题。这对我来说感觉更干净。