如何通过response.write在node.js中正确发送缓冲区?
我正在尝试从node.js服务器发送二进制内容。为此,我分配一个缓冲区并用我的内容填充缓冲区,然后对其调用如何通过response.write在node.js中正确发送缓冲区?,node.js,node.js-buffer,Node.js,Node.js Buffer,我正在尝试从node.js服务器发送二进制内容。为此,我分配一个缓冲区并用我的内容填充缓冲区,然后对其调用response.write()。一旦它返回,我就用新内容重用缓冲区。然而,由于某些原因,它似乎不能正常工作 以下是服务器代码: const http = require('http'); async function sendChunk( response, outbuf ) { console.log( "Sending buffer: %s", outbuf );
response.write()
。一旦它返回,我就用新内容重用缓冲区。然而,由于某些原因,它似乎不能正常工作
以下是服务器代码:
const http = require('http');
async function sendChunk( response, outbuf )
{
console.log( "Sending buffer: %s", outbuf );
// Send the buffer out. If it returns false,
// this means the kernel buffers are full,
// and we have to wait until they are available.
if ( await response.write( outbuf ) === false )
{
await new Promise(resolve => response.once('drain', ()=>{
resolve();
}));
}
}
async function sendData( response )
{
let outbuf = Buffer.alloc( 20 );
for ( let count = 0x45; count < 0x50; count++ )
{
for ( let i = 0; i < outbuf.length; i++ )
{
outbuf[i] = count;
}
await sendChunk( response, outbuf );
}
}
function webRequestHandler( request, response )
{
let body = [];
request.on('error', (err) => {
console.error(err);
return;
});
request.on('data', (chunk) => {
body.push(chunk);
});
response.on('error', (err) => {
console.error( "Error sending response: %s", err);
return;
});
// A whole body collected - process it
request.on('end', async () => {
// Handle the update; can return an error message
response.setHeader('Content-Type', 'text/plain');
await sendData( response );
response.end();
});
}
const webserver = http.createServer( webRequestHandler );
// Create the web service
webserver.on('error', function (err) {
console.log("[" + process.pid + "] " + JSON.stringify(err));
process.exit();
});
webserver.listen( { "host" : "127.0.0.1", "port" : 5252 }, () => {
console.log( "Server running" );
});
然而,客户收到的却是完全不同的东西:
> curl http://localhost:5252/
EEEEEEEEEEEEEEEEEEEEOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
这是怎么回事?如果我在sendChunk中创建一个新的缓冲区(它是EXPUFF的一个副本),它确实可以工作。然而,这似乎是对RAM的浪费,对于来自C背景的人来说没有什么意义,而且一旦你在套接字上调用send()
,数据就被复制了,你可以随心所欲地重用源缓冲区
node.js的工作方式不同吗?我是否需要为response.write()创建一个专用缓冲区,在调用write后,即使write已返回,并且我等待drain
事件,也不能再对其进行操作?我已经发布了一条重要的评论,该评论被关闭:
您应该将回调传递给.write(),以了解节点何时启动
完成了那块内存,而不是依赖于“drain”
事件
一旦进行了更改,您将在
你在期待
实际上,一旦sendcunk
函数更改如下:
Sending buffer: EEEEEEEEEEEEEEEEEEEE
Sending buffer: FFFFFFFFFFFFFFFFFFFF
Sending buffer: GGGGGGGGGGGGGGGGGGGG
Sending buffer: HHHHHHHHHHHHHHHHHHHH
Sending buffer: IIIIIIIIIIIIIIIIIIII
Sending buffer: JJJJJJJJJJJJJJJJJJJJ
Sending buffer: KKKKKKKKKKKKKKKKKKKK
Sending buffer: LLLLLLLLLLLLLLLLLLLL
Sending buffer: MMMMMMMMMMMMMMMMMMMM
Sending buffer: NNNNNNNNNNNNNNNNNNNN
Sending buffer: OOOOOOOOOOOOOOOOOOOO
async function sendChunk( response, outbuf )
{
return new Promise( function( resolve, reject) {
if ( response.write( outbuf, ()=>{ resolve(); } ) === false )
{
console.log( "Draining buffer" );
response.once('drain', ()=>{
resolve();
});
}
});
}
所以我们只在函数回调中解决它,问题就消失了。这里的核心问题是,response.write
是不可等待的,并且在调用回调之前返回
我应该更仔细地阅读文档。我发布了一条重要的评论:
您应该将回调传递给.write(),以了解节点何时启动
完成了那块内存,而不是依赖于“drain”
事件
一旦进行了更改,您将在
你在期待
实际上,一旦sendcunk
函数更改如下:
Sending buffer: EEEEEEEEEEEEEEEEEEEE
Sending buffer: FFFFFFFFFFFFFFFFFFFF
Sending buffer: GGGGGGGGGGGGGGGGGGGG
Sending buffer: HHHHHHHHHHHHHHHHHHHH
Sending buffer: IIIIIIIIIIIIIIIIIIII
Sending buffer: JJJJJJJJJJJJJJJJJJJJ
Sending buffer: KKKKKKKKKKKKKKKKKKKK
Sending buffer: LLLLLLLLLLLLLLLLLLLL
Sending buffer: MMMMMMMMMMMMMMMMMMMM
Sending buffer: NNNNNNNNNNNNNNNNNNNN
Sending buffer: OOOOOOOOOOOOOOOOOOOO
async function sendChunk( response, outbuf )
{
return new Promise( function( resolve, reject) {
if ( response.write( outbuf, ()=>{ resolve(); } ) === false )
{
console.log( "Draining buffer" );
response.once('drain', ()=>{
resolve();
});
}
});
}
所以我们只在函数回调中解决它,问题就消失了。这里的核心问题是,response.write
是不可等待的,并且在调用回调之前返回
应该更仔细地阅读文档。我不确定您的实际问题是什么,但您不能使用
等待和响应。编写。这是因为它是一个流,而不是一个承诺(流和承诺都只是处理异步操作的设计模式,但它们有不同的API,例如承诺有async/await)。诚然,在这种情况下,它是一个不可操作的(等待什么也不做),但它可能会误导你的反应。写入回调,但它没有改变任何东西,所以我怀疑问题是否存在。谢谢你的评论。我不确定你的实际问题是什么,但是你不能用等待和响应。写。这是因为它是一个流,而不是一个承诺(流和承诺都只是处理异步操作的设计模式,但它们有不同的API,例如承诺有async/await)。诚然,在这种情况下,它是一个不可操作的(等待什么也不做),但它可能会误导你的反应。写入回调,但它没有改变任何东西,所以我怀疑问题是否存在。谢谢你的评论。