Następujący kod Wyświetla dwukrotnie numer portu 40001, a następnie wyjść z błędem:

Error: listen EADDRINUSE

Uważam, że jest to dlatego, że kod jest asynchroniczny i nie czeka na jedną całą iterację pętli Foreach przed przypisaniem innego portu.

Który węzeł idiom powinien użyć do rozwiązania tego? Chcę pętli nad tablicą i zrobić połączenie Phantomjów na innym porcie na każdej iteracji.

posts.forEach(function(element, index, posts){

        portscanner.findAPortNotInUse(40000, 60000, 'localhost', function(err, freeport) {
        if(err) {
            console.log(err);
        }
            console.log(freeport); //outputs 40001 twice then exits
            phantom.create({'port': freeport}, function(ph){

                return ph.createPage(function(page) {
                    return page.open("http://www.target.com/showthread.php?t="+posts[index].post_id, function(status) {
                        console.log("opened post? ", status);

                        return page.get('plainText', function(content){
                            console.log(content);
                            return ph.exit();
                        });
                    });
                });
            });
        });
    });
0
codecowboy 3 grudzień 2013, 20:05

2 odpowiedzi

Najlepsza odpowiedź

Więc masz rację. Problem polega na tym, że po znalezieniu portu na pierwszej iteracji (40001) nie zużywasz go przed następną iteracji, więc 40001 znajduje się dwa razy.

Więc są tutaj 2 podejścia. Albo używasz kontynuacji, tj. Utworzysz następny krok do wykonania jako funkcja, a następnie zadzwoń do kontynuacji po spożyciu portu.

W tym przypadku prawdopodobnie łatwiej jest choć utwór portu. Zacznij od definiowania portu podstawowego w 40000, gdy znajdziesz port, ustaw port podstawowy do freeport + 1 i wyszukaj ten zakres.

var startPort = 40000
var endPort = 60000

posts.forEach(function(element, index, posts){

    portscanner.findAPortNotInUse(startPort, endPort, 'localhost', function(err, freeport) {
        if(err) {
            return console.log(err);
        }
        console.log(freeport);

        startPort = freeport + 1 // correct the start port to search from

        phantom.create({'port': freeport}, function(ph){

            return ph.createPage(function(page) {
                return page.open("http://www.target.com/showthread.php?t="+posts[index].post_id, function(status) {
                    console.log("opened post? ", status);

                    return page.get('plainText', function(content){
                        console.log(content);
                        return ph.exit();
                    });
                });
            });
        });
    });
});

Kontynuacja przy użyciu ciągłej serii (nie testowana, ale powinna dać pomysł)

var phantom = require("phantom")
var portscanner = require("portscanner")
var series = require("continuable-series");

module.exports = function processPosts(posts) {

    var callInSeries = posts.map(function (post) {
        return phantomPage.bind(null, post)
    });

    series(callInSeries, function (err) {
        if (err) {
            console.log(err)
        }
    }
}    

function phantomPage(post, callback) {
    portscanner.findAPortNotInUse(40000, 60000, 'localhost', function(err, freeport) {
        if (err) {
            return callback(err);
        }

        phantom.create({'port': freeport}, function(ph){
            // Now that we have opened the port, we can callback immediately
            // starting the next iteration
            callback(null)

            return ph.createPage(function(page) {
                return page.open("http://www.target.com/showthread.php?t="+post.post_id, function(status) {
                    console.log("opened post? ", status);

                    return page.get('plainText', function(content){
                        console.log(content);
                        return ph.exit();
                    });
                });
            });
        });
    });
}
3
Matt Esch 3 grudzień 2013, 16:43

Niedawno wpadłem do tego samego problemu i naprawiłem go za pomocą Math.Random, aby wygenerować wartość portu startowego i właśnie dodano 500, aby uzyskać wartość portu końcowego.

function getRandomInt(min, max) {
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (max - min)) + min;
}

var startPort = getRandomInt(3000, 8000);
var endPort = startPort + 500;

portscan.findAPortNotInUse(startPort, endPort, '127.0.0.1', function (err, ports) {
   .....
}
1
Grant81 31 maj 2017, 06:02