[英]Socket ReceiveAsync, Timeouts and Questions
I need to reimplement a database connection driver for some legacy cobol
database for one of my customers. 我需要为我的一位客户的一些旧版cobol
数据库重新实现数据库连接驱动程序。 The way the application is built, i cannot use async/await
(just leave it like that, i know it is stupid). 应用程序的构建方式,我不能使用async/await
(就这样吧,我知道它很愚蠢)。 The whole application is an ASP.NET API. 整个应用程序是一个ASP.NET API。
The old driver uses a c++ dll, that is included with inter-op methods. 旧驱动程序使用c ++ dll,该文件已包含在互操作方法中。 The idea behind the old system is: use one connection to the db for everything, have multiple threads send a packet and have one thread that receives the answers and delegates them to the right thread. 旧系统背后的想法是:使用一个连接到数据库的所有东西,让多个线程发送一个数据包,让一个线程接收答案并将它们委托给正确的线程。 To keep the connection alive, one needs to send some sort of ping message to database and handle its pong message. 为了使连接保持活动状态,需要向数据库发送某种ping消息并处理其pong消息。
I reimplemented that as POC in c#, have one connection, open a background thread and use AutoResetEvents to notify the right threads that the answer is ready to be processed. 我重新实现了,作为c#中的POC,建立一个连接,打开一个后台线程,并使用AutoResetEvents通知正确的线程已经准备好处理该答案。 I set the ReceiveTimeout to 5 seconds, and while there was nobody sending data to the server, the receive timeout helped me to send the ping-message to the server. 我将ReceiveTimeout设置为5秒,虽然没有人向服务器发送数据,但是接收超时帮助我将ping消息发送到服务器。
A reason for the rewrite is, that the one-connection-solution does not scale. 重写的原因是单连接解决方案无法扩展。
So, my idea is to use a socket pool and ReceiveAsync
with SocketAsyncEventArgs
on the sockets. 因此,我的想法是在套接字上使用套接字池和带有SocketAsyncEventArgs
ReceiveAsync
。 The solution works so far, but not really good. 到目前为止,该解决方案仍然有效,但效果不是很好。 Here are some questions: 这里有一些问题:
ReceiveAsync
, is there a other way then a timer to send my ping-messages 由于ReceiveTimeout与ReceiveAsync
不兼容,是否有其他方法可以通过计时器发送我的ping消息 ReceiveAsync
, can i still use normal Send
to send data, or do i have to use SendAsync
? 使用ReceiveAsync
,我是否仍可以使用常规的Send
发送数据,还是必须使用SendAsync
? ReceiveAsync
does not receive all required data, may i use Receive
to read the rest of it, or is it better to use ReceiveAsync
again for the missing data? 当ReceiveAsync
未接收到所有必需的数据时,我可以使用Receive
读取其余数据,还是对丢失的数据再次使用ReceiveAsync
更好? use AutoResetEvents to notify the right threads that the answer is ready to be processed. 使用AutoResetEvents通知正确的线程,该答案已准备好进行处理。
May I suggest a thread-safe queue? 我可以建议一个线程安全队列吗? BlockingCollection<T>
or BufferBlock<T>
? BlockingCollection<T>
或BufferBlock<T>
?
I set the ReceiveTimeout to 5 seconds, and while there was nobody sending data to the server, the receive timeout helped me to send the ping-message to the server. 我将ReceiveTimeout设置为5秒,虽然没有人向服务器发送数据,但是接收超时帮助我将ping消息发送到服务器。
This is weird. 真奇怪 I assume the entire protocol is ping-pong based, or else using a receive timeout to send messages would not work. 我假设整个协议都是基于ping-pong的,否则使用接收超时发送消息将不起作用。
my idea is to use a socket pool and ReceiveAsync with SocketAsyncEventArgs on the sockets 我的想法是在套接字上使用套接字池和带有SocketAsyncEventArgs的ReceiveAsync
If you can't use async
/ await
, I would advise switching to the Begin*
/ End*
style of asynchronous API. 如果您不能使用async
/ await
,我建议您切换到异步API的Begin*
/ End*
样式。 Going straight from synchronous to SocketAsyncEventArgs
is quite a leap; 从同步直接变为SocketAsyncEventArgs
是一个飞跃。 SocketAsyncEventArgs
is the most difficult form of socket async
programming. SocketAsyncEventArgs
是套接字async
编程的最困难形式。
is there a other way then a timer to send my ping-messages 还有其他方法可以通过计时器发送我的ping消息
I would recommend a timer; 我建议一个计时器。 that's the normal solution for heartbeat messages. 这是心跳消息的正常解决方案。 The desired semantics should be "we want to send data at least this often". 所需的语义应该是“我们至少要经常发送数据”。 So use a timer that you can reset when sending regular messages (not receiving messages). 因此,请使用可以在发送常规消息(不接收消息)时重置的计时器。
when using ReceiveAsync, can i still use normal Send to send data, or do i have to use SendAsync? 使用ReceiveAsync时,我是否仍可以使用正常的Send发送数据,还是必须使用SendAsync?
You should be able to use synchronous for one stream and asynchronous for the other. 您应该能够对一个流使用同步,而对另一个流使用异步。 I've never tried this, though; 我从来没有尝试过; all systems I've worked on are fully asynchronous. 我研究过的所有系统都是完全异步的。
when ReceiveAsync does not receive all required data, may i use Receive to read the rest of it, or is it better to use ReceiveAsync again for the missing data? 当ReceiveAsync未接收到所有必需的数据时,我可以使用Receive读取其余数据,还是对丢失的数据再次使用ReceiveAsync更好?
This question doesn't make as much sense to me. 这个问题对我来说意义不大。 If you're asynchronously reading, you shouldn't block the calling thread. 如果您正在异步读取,则不应阻塞调用线程。
Also, I think this question is framed from the wrong perspective. 另外,我认为这个问题是从错误的角度提出的。 It seems like the code wants to "receive the next message", but this is a problematic way to approach reading from a socket. 代码似乎想“接收下一条消息”,但这是从套接字读取数据的一种有问题的方式。 Instead, I recommend that your code have a loop that endlessly reads from the socket and passes that data to another type that buffers it as necessary and pushes out messages as they finish. 相反,我建议您的代码具有一个循环,该循环不断地从套接字读取数据,并将该数据传递给另一种类型,该数据在必要时对其进行缓冲,并在完成消息时将其推出。
is this a known behaviour when debugging an IIS process under load? 负载下调试IIS进程时,这是一种已知的行为吗?
I would not expect so, but I don't have much IIS load testing experience. 我不希望如此,但是我没有太多的IIS负载测试经验。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.