简体   繁体   English

使用带有 node.js 的 http 连接未关闭

[英]Connection not closing using http with node.js

I have written the following function in Node.js in order to get json data from another server, with a view to saving it in a database and doing further processing.我在 Node.js 中编写了以下函数,以便从另一台服务器获取 json 数据,以便将其保存在数据库中并进行进一步处理。 The current function is:目前的功能是:

const db = require('../models/db.js')    
const gameHistDB = db.gameHistDB
const gameControlDB = db.gameControlDB
const http = require('http')

const playMove = async (req, res) => {
    try{
        console.log("playing")
        var playOptions = {
            hostname:'115.146.93.216',
            port: 5000,
            path: '/action/a159257a6840135d2edd5a3de3017356/game1/46',
            method: 'GET',
            agent:false,
            Connection:'close'
        }
        console.log(playOptions.path)
        var returnedData;
        var req = http.request(playOptions, res => {
            console.log(res.statusCode)

            let data = ''
            res.on('data',(d) => {
                data += d;
                console.log(d)
            });

            res.on('close',()=>{
                returnedData = JSON.parse(data)
                console.log(returnedData.turninfo.gamestep)
                // gameHistDB.insert(returnedData)
            });

        })

        req.on('error',error => {
            console.error(error)
        })

        req.end()
        console.log('Note that we got here')

    } catch (err) {
        console.log(err)
    }
}

(this is possibly a little more complex than it needs to be, but I'm trying to see exactly what is happening at what point) (这可能比它需要的要复杂一些,但我试图确切地了解在什么时候发生了什么)

When I invoke this the browser hangs in "getting data" mode and doesn't seem to get to a state where it thinks all the data has been processed, although it is definitely going into the 'on close' block and logging the right data.当我调用它时,浏览器挂在“获取数据”模式下,似乎没有进入它认为所有数据都已处理的状态,尽管它肯定会进入“关闭”块并记录正确的数据. If I uncomment the code which is inserting the requested json into the database then very nasty stuff happens, with constant nano errors telling me to revalidate the cache.如果我取消注释将请求的 json 插入到数据库中的代码,那么会发生非常讨厌的事情,持续的 nano 错误告诉我重新验证缓存。

I'm also unsure whether it's good workflow to do the database queries within res.on('close') - in other functions where I'm dealing with db queries I'm using await to ensure the query completes before doing other stuff, but it seems like I can't do that here.我也不确定在 res.on('close') 中执行数据库查询是否是好的工作流程 - 在我处理数据库查询的其他函数中,我使用 await 来确保查询在执行其他操作之前完成,但似乎我不能在这里做到这一点。

Any help appreciated任何帮助表示赞赏

EDIT: As in comments, I think maybe it is the json sending code on the other machine which is at fault.编辑:在评论中,我认为可能是另一台机器上的 json 发送代码有问题。 That is:那是:

try{
    console.log("playing")

    ...

    const python = spawn('python3',['./playGameMove.py',JSON.stringify(gamestep),req.params.move]);
    python.stdout.on('data',function(data){
        console.log('Getting data from playGameMove.py');
        nextState.push(data);
    });
    python.on('close',(code) => {
        console.log('in close');
        res.send(nextState.join(""))
    });
}catch(err){
    console.log(err)
}

Is there something I should do after res.send to ensure this code knows that it's done?在 res.send 之后我应该做些什么来确保此代码知道它已完成?

There are three main problems with your code.您的代码存在三个主要问题。

  1. You are naming two "req" and two "res"您正在命名两个“req”和两个“res”
  2. The execution order is not what you think.执行顺序不是你想的那样。 You are closing the request immediately, before anything happens (welcome to the world of asynchronism)您将在任何事情发生之前立即关闭请求(欢迎来到异步世界)
  3. You are not replying to the browser, which leaves it hanging.您没有回复浏览器,这会使其挂起。

Below are comments about all that's wrong with your current code.以下是关于您当前代码的所有错误的评论。 (I have removed the try/catch block because it's useless, you have error management with req.on('error') , nothing else should fail) (我已经删除了try/catch块,因为它没用,你可以使用req.on('error')进行错误管理,其他都不会失败)

const playMove = async (req, res) => { // No need for the "async" keyword. You're not using its counterpart, "await".

    var playOptions = { /* ... */ }
    var returnedData;

    // Problem here, you have called "req" like the other "req" from line 1. Now you have two "req"... Which is which?
    var req = http.request(playOptions, res => { // Executed 1st

        // Problem here, you have called "res" like the other "res" from line 1. Now you have two "res"... Which is which?

        console.log(res.statusCode)  // Executed 5th

        let data = ''
        res.on('data', (d) => {  // Executed 6th
            data += d;
            console.log(d)  // Executed 7th, 7th, 7th, every time there's a data coming in
        });

        res.on('close', () => { // Executed 8th
            returnedData = JSON.parse(data) // Executed 9th
            console.log(returnedData.turninfo.gamestep) // Executed 10th
            // gameHistDB.insert(returnedData)
        });

    })

    req.on('error', error => {  // Executed 2nd
        console.error(error)
    })

    req.end()  // Executed 3rd

    console.log('Note that we got here')  // Executed 4th
}

Here's a corrected version :这是一个更正的版本:

const playMove = (req, res) => {

    var playOptions = { /* ... */ }
    var returnedData;

    var reqHTTP = http.request(playOptions, resHTTP => { // Executed 1st. Using different names to not mix things up.

        console.log(resHTTP.statusCode)  // Executed 4th

        let data = ''
        resHTTP.on('data', (d) => {  // Executed 5th
            data += d;
            console.log(d)  // Executed 6th, 6th, 6th, every time there's a data coming in
        });

        resHTTP.on('close', () => { // Executed 7th
            returnedData = JSON.parse(data) // Executed 8th
            console.log(returnedData.turninfo.gamestep) // Executed 9th
            // gameHistDB.insert(returnedData)
            reqHTTP.end()  // Executed 10th

            res.send(returnedData); // Now reply to the browser! Executed 11th
        });

    })

    req.on('error', error => {  // Executed 2nd
        console.error(error)
    })

    console.log('Note that we got here')  // Executed 3rd
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM