在 Electron 主进程中发起 HTTP 请求访问 IP 话机接口:
fetch(`http://${phoneActionIp}/xxxx/sanshi.com?key=${key}`, {
method: 'GET',
headers: {
Authorization: 'Basic ' + Buffer.from('admin:admin').toString('base64'),
}
})
当短时间内连续请求多次时,接口报错:
问题原因
Node 的 fetch 默认使用 HTTP Keep-Alive 长连接机制,重用之前的 TCP 连接从而提高性能;
而 IP 话机上的 HTTP 服务一般是嵌入式 CGI 服务器(如 boa、thttpd、microhttpd),这些服务一般只实现了 HTTP/1.0 或非常简化的 1.1,不支持复用 TCP 连接,每次响应后立即 close。
触发流程
请求1完成后: Node 保留 TCP 连接在连接池中,话机的服务端却已经关闭了 socket。
请求2时: Node 尝试复用“已关闭”的 TCP 连接,这时已经连接不到话机服务器了,话机返回 TCP RST(Rest) 包,Node 抛出 ECONNRESET。
解决方案
定义请求头中 Connection 属性为 close,表示请求完成后主动关闭连接,下次重新建立新的 TCP。
fetch(url, {
headers: {
Connection: 'close'
}