簡體   English   中英

使用帶有 node.js 的 http 連接未關閉

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

我在 Node.js 中編寫了以下函數,以便從另一台服務器獲取 json 數據,以便將其保存在數據庫中並進行進一步處理。 目前的功能是:

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)
    }
}

(這可能比它需要的要復雜一些,但我試圖確切地了解在什么時候發生了什么)

當我調用它時,瀏覽器掛在“獲取數據”模式下,似乎沒有進入它認為所有數據都已處理的狀態,盡管它肯定會進入“關閉”塊並記錄正確的數據. 如果我取消注釋將請求的 json 插入到數據庫中的代碼,那么會發生非常討厭的事情,持續的 nano 錯誤告訴我重新驗證緩存。

我也不確定在 res.on('close') 中執行數據庫查詢是否是好的工作流程 - 在我處理數據庫查詢的其他函數中,我使用 await 來確保查詢在執行其他操作之前完成,但似乎我不能在這里做到這一點。

任何幫助表示贊賞

編輯:在評論中,我認為可能是另一台機器上的 json 發送代碼有問題。 那是:

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)
}

在 res.send 之后我應該做些什么來確保此代碼知道它已完成?

您的代碼存在三個主要問題。

  1. 您正在命名兩個“req”和兩個“res”
  2. 執行順序不是你想的那樣。 您將在任何事情發生之前立即關閉請求(歡迎來到異步世界)
  3. 您沒有回復瀏覽器,這會使其掛起。

以下是關於您當前代碼的所有錯誤的評論。 (我已經刪除了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
}

這是一個更正的版本:

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