node.js - 在 'end' 事件之后调用“错误”事件?

标签 node.js http2

const http2 = require('http2');
const fs = require('fs');
function APICall(){
    return new Promise(function(resolve,reject){
        const client = http2.connect('https://localhost:8443', {
            ca: fs.readFileSync('localhost-cert.pem')
        });
        client.on('error', (err) => console.error(err));

        const req = client.request({ ':path': '/' });

        req.on('error', (error) => {
            console.log("error",error)
            reject("Could not connect with server");
        });

        req.setEncoding('utf8');
        let data = '';
        req.on('data', (chunk) => { data += chunk; });
        req.on('end', () => {
            console.log(`\n${data}`);
            resolve(data);
        });
    });
}

我创建了一个 http2 客户端(使用官方网站中提供的示例,但我在 Promise 中使用了它)。我遇到的问题是,即使我的服务器不可用,结束事件也会在错误事件之前调用。因此, promise 不会因错误而拒绝,而是会用空数据来解决。我该如何解决这个问题?

最佳答案

所以根据http2/core.js :

// Upon creation, the Http2Session takes ownership of the socket. The session
// may not be ready to use immediately if the socket is not yet fully connected.
// In that case, the Http2Session will wait for the socket to connect. Once
// the Http2Session is ready, it will emit its own 'connect' event.

//
// The Http2Session.goaway() method will send a GOAWAY frame, signalling
// to the connected peer that a shutdown is in progress. Sending a goaway
// frame has no other effect, however.
//
// Calling session.destroy() will tear down the Http2Session immediately,
// making it no longer usable. Pending and existing streams will be destroyed.
// The bound socket will be destroyed. Once all resources have been freed up,
// the 'close' event will be emitted. Note that pending streams will be
// destroyed using a specific "ERR_HTTP2_STREAM_CANCEL" error. Existing open
// streams will be destroyed using the same error passed to session.destroy()
//
// If destroy is called with an error, an 'error' event will be emitted
// immediately following the 'close' event.

//
// The socket and Http2Session lifecycles are tightly bound. Once one is
// destroyed, the other should also be destroyed. When the socket is destroyed
// with an error, session.destroy() will be called with that same error.
// Likewise, when session.destroy() is called with an error, the same error
// will be sent to the socket.

我认为这是预期的行为,首先流关闭,然后发出错误

根据上述文档,我添加了一个 connect 事件来查看发生了什么。当服务器不可用时,它不会发出 connect 事件,否则它会发出。

const http2 = require('http2');
const fs = require('fs');
function APICall(){
    return new Promise(function(resolve,reject){
        const client = http2.connect('http://localhost:8443', {
            // ca: fs.readFileSync('localhost-cert.pem')
        });
        client.on('error', (err) => console.error('client error'));

        const req = client.request({ ':path': '/' });

        client.on('connect', ()=>console.log('connect'))

        req.on('error', (error) => {
            reject("Could not connect with server");
        });

        req.setEncoding('utf8');
        let data = '';
        req.on('data', (chunk) => { data += chunk; });
        req.on('end', () => {
            console.log('ended');
            console.log(`\n${data}`);
            resolve(data);
        });
    });
}

何时 http://localhost:8443上升:

connect
ended

何时 http://localhost:8443下降:

ended
client error

因此,您可以使用 connect 事件检查是否有数据

注意:这是我阅读源代码的看法,我不知道这是否正确。请随意编辑答案并改进它。

关于node.js - 在 'end' 事件之后调用“错误”事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56832755/

相关文章:

git push with http/2 有时会挂起 "17 bytes stray data"

http2 - nghttp2 多部分 POST 消息

node.js - Aerospike - 在嵌套对象中添加新的键/值对

node.js - Node 需要语法

javascript - 未定义文档和窗口的Puppeteer Electron

firefox - 带有 HTTP/2 推送 promise 的 Firebug

http - 使用 HTTP/2 时可以有多个开放的 SSE channel 吗?

http - 对于单个请求,http/2 相对于 http 的性能优势

javascript - 启动 node.js 服务器

javascript - 来自控制台的错误消息指出 res 未定义