我有一段代码使用HTTP连接与第三方集成,从而以不同的方式处理套接字超时和连接超时。
我一直在尝试模拟和测试可能来自第三方的所有情况。通过连接到服务器防火墙阻止的端口能够测试连接超时端口81。
但是我无法模拟套接字超时。如果我的理解是正确的,那么套接字超时与连续的数据包流相关联,并且连接之间处于断开状态。有什么方法可以模拟吗?
答案 0 :(得分:0)
所以我们在这里讨论的超时是各种超时,一种是连接到服务器(连接超时),另一种超时会发生在一段时间内没有通过套接字发送或接收数据时(空闲超时)。< /p>
节点套接字有一个套接字超时,可用于综合连接和空闲超时。这可以通过将套接字超时设置为连接超时,然后在连接时将其设置为空闲超时来完成。
示例:
const request = http.request(url, {
timeout: connectTimeout,
});
request.setTimeout(idleTimeout);
这是可行的,因为在创建套接字时会立即设置选项中的超时,setTimeout
函数在连接时在套接字上运行!
无论如何,问题是关于如何测试连接超时。好的,让我们首先暂停空闲超时。我们可以通过在一段时间内不发送任何数据来简单地测试,这会导致超时。检查!
连接超时有点难测试,首先想到的是我们需要一个不会出错但也不会连接的地方来连接。这会导致超时。但是我们到底如何在节点中模拟它?
如果我们跳出框框思考一下,那么我们可能会发现这个超时时间大约是连接所需的时间。为什么连接需要那么长时间并不重要。我们只需要延迟连接所需的时间。这不一定是服务器的事情,我们也可以在客户端上做。毕竟这是连接的部分,如果我们可以延迟到那里,我们可以测试超时。
那么我们怎么能延迟客户端的连接呢?好吧,我们可以使用 DNS 查找。在建立连接之前,会进行 DNS 查找。如果我们只是将其延迟 5 秒左右,我们可以很容易地测试连接超时。
代码如下:
import * as dns from "dns";
import * as http from "http";
const url = new URL("http://localhost:8080");
const request = http.request(url, {
timeout: 3 * 1000, // connect timeout
lookup(hostname, options, callback) {
setTimeout(
() => dns.lookup(hostname, options, callback),
5 * 1000,
);
},
});
request.setTimeout(10 * 1000); // idle timeout
request.addListener("timeout", () => {
const message = !request.socket || request.socket.connecting ?
`connect timeout while connecting to ${url.href}` :
`idle timeout while connected to ${url.href}`;
request.destroy(new Error(message));
});
在我的项目中,我通常使用我注入的代理。然后代理进行延迟查找。像这样:
import * as dns from "dns";
import * as http from "http";
const url = new URL("http://localhost:8080");
const agent = new http.Agent({
lookup(hostname, options, callback) {
setTimeout(
() => dns.lookup(hostname, options, callback),
5 * 1000,
);
},
});
const request = http.request(url, {
timeout: 3 * 1000, // connect timeout
agent,
});
request.setTimeout(10 * 1000); // idle timeout
request.addListener("timeout", () => {
const message = !request.socket || request.socket.connecting ?
`connect timeout while connecting to ${url.href}` :
`idle timeout while connected to ${url.href}`;
request.destroy(new Error(message));
});
快乐编码!
答案 1 :(得分:-1)
“连接超时”确定建立TCP连接可能需要多长时间,而这一切都发生在通过该行发送任何HTTP相关数据之前。通过连接到阻塞的端口,由于未建立连接,因此您仅测试了部分连接超时。通常,将非常快速地创建(建立)本地网络上的TCP连接。但是,当连接到世界另一端的服务器时,建立TCP连接可能需要几秒钟。
“套接字超时”是一个有点令人误解的名称-它仅确定您(客户端)将等待服务器的答案(数据)多长时间。换句话说,Socket.read()
函数在等待数据时将阻塞多长时间。
正确测试这些功能涉及创建服务器套接字或(HTTP)Web服务器,您可以对其进行修改以使其变慢。描述如何创建和使用服务器套接字进行连接超时测试(如果可能的话)在这里无法回答,但是套接字超时测试是一个常见的问题-例如,请参见here(我只是用谷歌搜索“模拟网络”服务器来测试超时”),这会导致产生类似MockWebServer之类的工具。 “ MockWebServer”可能还可以选择测试连接超时(我没有使用“ MockWebServer”),但是如果没有,则可能有另一个工具。
最后一点:最好在超时设置方面测试第三方HTTP库的使用,即使这需要一些努力。可能发生的最坏情况是库中不使用代码中的套接字超时设置,而是使用默认的套接字超时“永远等待”。这可能会导致您的应用程序无缘无故地做任何事情(“挂起”)。