繁体   English   中英

套接字ReceiveAsync,超时和问题

[英]Socket ReceiveAsync, Timeouts and Questions

我需要为我的一位客户的一些旧版cobol数据库重新实现数据库连接驱动程序。 应用程序的构建方式,我不能使用async/await (就这样吧,我知道它很愚蠢)。 整个应用程序是一个ASP.NET API。

旧驱动程序使用c ++ dll,该文件已包含在互操作方法中。 旧系统背后的想法是:使用一个连接到数据库的所有东西,让多个线程发送一个数据包,让一个线程接收答案并将它们委托给正确的线程。 为了使连接保持活动状态,需要向数据库发送某种ping消息并处理其pong消息。

我重新实现了,作为c#中的POC,建立一个连接,打开一个后台线程,并使用AutoResetEvents通知正确的线程已经准备好处理该答案。 我将ReceiveTimeout设置为5秒,虽然没有人向服务器发送数据,但是接收超时帮助我将ping消息发送到服务器。

重写的原因是单连接解决方​​案无法扩展。

因此,我的想法是在套接字上使用套接字池和带有SocketAsyncEventArgs ReceiveAsync 到目前为止,该解决方案仍然有效,但效果不是很好。 这里有一些问题:

  • 由于ReceiveTimeout与ReceiveAsync不兼容,是否有其他方法可以通过计时器发送我的ping消息
  • 使用ReceiveAsync ,我是否仍可以使用常规的Send发送数据,还是必须使用SendAsync
  • ReceiveAsync未接收到所有必需的数据时,我可以使用Receive读取其余数据,还是对丢失的数据再次使用ReceiveAsync更好?
  • 可能无关紧要:我使用大炮对新驱动程序进行了一些性能测试; 他们不时地在30秒后超时(这是我设置的db-transaction超时); 当我尝试调试即使未命中断点时, 炮兵也会获得ESOCKETTIMEDOUT-在负载下调试IIS进程时,这是已知行为吗?

使用AutoResetEvents通知正确的线程,该答案已准备好进行处理。

我可以建议一个线程安全队列吗? BlockingCollection<T>BufferBlock<T>

我将ReceiveTimeout设置为5秒,虽然没有人向服务器发送数据,但是接收超时帮助我将ping消息发送到服务器。

真奇怪 我假设整个协议都是基于ping-pong的,否则使用接收超时发送消息将不起作用。

我的想法是在套接字上使用套接字池和带有SocketAsyncEventArgs的ReceiveAsync

如果您不能使用async / await ,我建议您切换到异步API的Begin* / End*样式。 从同步直接变为SocketAsyncEventArgs是一个飞跃。 SocketAsyncEventArgs是套接字async编程的最困难形式。

还有其他方法可以通过计时器发送我的ping消息

我建议一个计时器。 这是心跳消息的正常解决方案。 所需的语义应该是“我们至少要经常发送数据”。 因此,请使用可以在发送常规消息(不接收消息)时重置的计时器。

使用ReceiveAsync时,我是否仍可以使用正常的Send发送数据,还是必须使用SendAsync?

您应该能够对一个流使用同步,而对另一个流使用异步。 我从来没有尝试过; 我研究过的所有系统都是完全异步的。

当ReceiveAsync未接收到所有必需的数据时,我可以使用Receive读取其余数据,还是对丢失的数据再次使用ReceiveAsync更好?

这个问题对我来说意义不大。 如果您正在异步读取,则不应阻塞调用线程。

另外,我认为这个问题是从错误的角度提出的。 代码似乎想“接收下一条消息”,但这是从套接字读取数据的一种有问题的方式。 相反,我建议您的代码具有一个循环,该循环不断地从套接字读取数据,并将该数据传递给另一种类型,该数据在必要时对其进行缓冲,并在完成消息时将其推出。

负载下调试IIS进程时,这是一种已知的行为吗?

我不希望如此,但是我没有太多的IIS负载测试经验。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM