英文:
How to make two requests using the same socket?
问题
这段代码发出了两个请求,但它们使用了不同的套接字。您想要配置Server
或请求Agent
以使这两个请求使用相同的套接字。
以下是可能的结果:
Socket.localPort 3000
Socket.remotePort 38880
Server_request
{
host: '127.0.0.1:3000',
connection: 'keep-alive',
'content-length': '1'
}
IncomingMessage.socket.remotePort 38880
IncomingMessage_data
IncomingMessage_end
IncomingMessage_close
{
date: 'Sun, 21 May 2023 18:53:56 GMT',
connection: 'keep-alive',
'keep-alive': 'timeout=5',
'content-length': '0'
}
Socket_close
Socket.localPort 3000
Socket.remotePort 34564
Server_request
{
host: '127.0.0.1:3000',
connection: 'keep-alive',
'content-length': '1'
}
IncomingMessage.socket.remotePort 34564
IncomingMessage_data
IncomingMessage_end
IncomingMessage_close
{
date: 'Sun, 21 May 2023 18:54:01 GMT',
connection: 'keep-alive',
'keep-alive': 'timeout=5',
'content-length': '0'
}
Socket_close
这是可能的结果的输出。
英文:
This code makes two requests. However, they use different sockets. How can I configure the Server
or request Agent
in order for both requests to use the same socket?
import { Server, IncomingMessage, ServerResponse, Agent, request } from 'node:http';
import { Socket } from 'node:net';
console.log('\n\n');
let server = new Server({ keepAlive: true});
server.addListener('request', (req: IncomingMessage, res: ServerResponse) => {
console.log('Server_request');
console.log(req.headers);
console.log('IncomingMessage.socket.remotePort', req.socket.remotePort);
let data = '';
req.addListener('data', (chunk: string) => {
console.log('IncomingMessage_data');
data = data + chunk;
})
req.addListener('close', () => {
console.log('IncomingMessage_close');
});
req.addListener('end', () => {
console.log('IncomingMessage_end');
res.end('');
});
})
server.listen(3000, "127.0.0.1");
server.addListener('close', () => console.log('sever_close'));
server.addListener('connection', (socket: Socket) => {
// "This event is emitted when a new TCP stream is established (https://nodejs.org/api/http.html#event-connection)."
socket.addListener('close', () => console.log('Socket_close'));
console.log("Socket.localPort", socket.localPort);
console.log("Socket.remotePort", socket.remotePort);
})
let agent = new Agent({ keepAlive: true, maxSockets: 1});
let req0 = request(
{
agent: agent,
hostname: '127.0.0.1',
port: 3000,
path: '/',
method: 'POST'
}, (res:IncomingMessage)=>{
console.log(res.headers);
});
req0.end("0");
let req1 = request(
{
agent: agent,
hostname: '127.0.0.1',
port: 3000,
path: '/',
method: 'POST'
}, (res:IncomingMessage)=>{
console.log(res.headers);
});
req1.end("1");
This is a possible result:
Socket.localPort 3000
Socket.remotePort 38880
Server_request
{
host: '127.0.0.1:3000',
connection: 'keep-alive',
'content-length': '1'
}
IncomingMessage.socket.remotePort 38880
IncomingMessage_data
IncomingMessage_end
IncomingMessage_close
{
date: 'Sun, 21 May 2023 18:53:56 GMT',
connection: 'keep-alive',
'keep-alive': 'timeout=5',
'content-length': '0'
}
Socket_close
Socket.localPort 3000
Socket.remotePort 34564
Server_request
{
host: '127.0.0.1:3000',
connection: 'keep-alive',
'content-length': '1'
}
IncomingMessage.socket.remotePort 34564
IncomingMessage_data
IncomingMessage_end
IncomingMessage_close
{
date: 'Sun, 21 May 2023 18:54:01 GMT',
connection: 'keep-alive',
'keep-alive': 'timeout=5',
'content-length': '0'
}
Socket_close
答案1
得分: 1
以下是您要翻译的代码部分:
The "trick" here is to drain the response; this allows for the subsequent request to proceed using the same socket before it closes (i.e., the res.resume();):
import { Server, IncomingMessage, ServerResponse, Agent, request } from 'node:http';
import { Socket } from 'node:net';
console.log('\n\n');
let server = new Server({ keepAlive: true, keepAliveTimeout: 4000 });
server.addListener('request', (req: IncomingMessage, res: ServerResponse) => {
console.log('Server_request');
console.log(req.headers);
console.log('IncomingMessage.socket.remotePort', req.socket.remotePort);
let data = '';
req.addListener('data', (chunk: string) => {
console.log('IncomingMessage_data');
data = data + chunk;
});
req.addListener('close', () => {
console.log('IncomingMessage_close');
});
req.addListener('end', () => {
console.log('IncomingMessage_end');
res.end('');
});
});
server.listen(3000, "127.0.0.1");
server.addListener('close', () => console.log('Server_close'));
server.addListener('connection', (socket: Socket) => {
// "This event is emitted when a new TCP stream is established (https://nodejs.org/api/http.html#event-connection)."
socket.addListener('close', () => console.log('Socket_close'));
console.log("Socket.localPort", socket.localPort);
console.log("Socket.remotePort", socket.remotePort);
})
let agent = new Agent({ keepAlive: true, maxSockets: 1, timeout: 2000 });
// The agent will keep the socket open for 2 seconds.
let req0 = request(
{
agent: agent,
hostname: '127.0.0.1',
port: 3000,
path: '/',
method: 'POST'
}, (res: IncomingMessage) => {
console.log(res.headers);
res.resume();
});
req0.end("0");
// The Socket is still open; hence, make another request using the same destination port number (i.e., the same socket).
let req1 = request(
{
agent: agent,
hostname: '127.0.0.1',
port: 3000,
path: '/',
method: 'POST'
}, (res: IncomingMessage) => {
console.log(res.headers);
res.resume();
// Drain the Readable.
});
req1.end("1");
setTimeout(() => {
// Use the same agent to make another request.
// The Socket has been closed (> 2000ms); hence, this request will likely have a different destination port number (i.e., a new Socket).
let req2 = request(
{
agent: agent,
hostname: '127.0.0.1',
port: 3000,
path: '/',
method: 'POST'
}, (res: IncomingMessage) => {
console.log(res.headers);
res.resume();
// Drain the Readable.
});
req2.end("2");
}, 5000);
英文:
The "trick" here is to drain the response; this allows for the subsequent request to proceed using the same socket before it closes (i.e., the res.resume();):
import { Server, IncomingMessage, ServerResponse, Agent, request } from 'node:http';
import { Socket } from 'node:net';
console.log('\n\n');
let server = new Server({ keepAlive: true, keepAliveTimeout: 4000 });
server.addListener('request', (req: IncomingMessage, res: ServerResponse) => {
console.log('Server_request');
console.log(req.headers);
console.log('IncomingMessage.socket.remotePort', req.socket.remotePort);
let data = '';
req.addListener('data', (chunk: string) => {
console.log('IncomingMessage_data');
data = data + chunk;
});
req.addListener('close', () => {
console.log('IncomingMessage_close');
});
req.addListener('end', () => {
console.log('IncomingMessage_end');
res.end('');
});
});
server.listen(3000, "127.0.0.1");
server.addListener('close', () => console.log('Server_close'));
server.addListener('connection', (socket: Socket) => {
// "This event is emitted when a new TCP stream is established (https://nodejs.org/api/http.html#event-connection)."
socket.addListener('close', () => console.log('Socket_close'));
console.log("Socket.localPort", socket.localPort);
console.log("Socket.remotePort", socket.remotePort);
})
let agent = new Agent({ keepAlive: true, maxSockets: 1, timeout: 2000 });
// The agent will keep the socket open for 2 seconds.
let req0 = request(
{
agent: agent,
hostname: '127.0.0.1',
port: 3000,
path: '/',
method: 'POST'
}, (res: IncomingMessage) => {
console.log(res.headers);
res.resume();
});
req0.end("0");
// The Socket is still open; hence, make another request using the same destination port number (i.e., the same socket).
let req1 = request(
{
agent: agent,
hostname: '127.0.0.1',
port: 3000,
path: '/',
method: 'POST'
}, (res: IncomingMessage) => {
console.log(res.headers);
res.resume();
// Drain the Readable.
});
req1.end("1");
setTimeout(() => {
// Use the same agent to make another request.
// The Socket has been closed (> 2000ms); hence, this request will likely have a different destination port number (i.e., a new Socket).
let req2 = request(
{
agent: agent,
hostname: '127.0.0.1',
port: 3000,
path: '/',
method: 'POST'
}, (res: IncomingMessage) => {
console.log(res.headers);
res.resume();
// Drain the Readable.
});
req2.end("2");
}, 5000);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论