NodeJS: จะรับพอร์ตของเซิร์ฟเวอร์ได้อย่างไร


142

คุณมักจะเห็นตัวอย่างสวัสดีรหัสโลกสำหรับโหนดที่สร้างเซิร์ฟเวอร์ Http เริ่มฟังพอร์ตจากนั้นตามด้วยบางสิ่งในบรรทัด:

console.log('Server is listening on port 8000');

แต่ในอุดมคติคุณจะต้องการสิ่งนี้แทน:

console.log('Server is listening on port ' + server.port);

ฉันจะดึงพอร์ตที่เซิร์ฟเวอร์กำลังฟังอยู่โดยไม่เก็บหมายเลขไว้ในตัวแปรก่อนการโทรได้server.listen()อย่างไร?

ฉันเคยเห็นสิ่งนี้ทำมาก่อน แต่ไม่พบในเอกสารประกอบของ Node อาจเป็นสิ่งที่เฉพาะเจาะจงในการแสดง?


3
ค้นหาในreq.headers.host
Andrew_1510

คำตอบ:


161

Express 4.x คำตอบ:

Express 4.x (ตามคำตอบของ Tien Do ด้านล่าง) ตอนนี้ถือว่า app.listen () เป็นการดำเนินการแบบอะซิงโครนัสดังนั้น listener.address () จะส่งคืนข้อมูลภายใน callback ของ app.listen ():

var app = require('express')();

var listener = app.listen(8888, function(){
    console.log('Listening on port ' + listener.address().port); //Listening on port 8888
});

แสดง 3 คำตอบ:

ฉันคิดว่าคุณกำลังมองหาสิ่งนี้ (เจาะจงเฉพาะ):

console.log("Express server listening on port %d", app.address().port)

คุณอาจเห็นสิ่งนี้ (บรรทัดล่างสุด) เมื่อคุณสร้างโครงสร้างไดเรกทอรีจากexpressคำสั่ง:

alfred@alfred-laptop:~/node$ express test4
   create : test4
   create : test4/app.js
   create : test4/public/images
   create : test4/public/javascripts
   create : test4/logs
   create : test4/pids
   create : test4/public/stylesheets
   create : test4/public/stylesheets/style.less
   create : test4/views/partials
   create : test4/views/layout.jade
   create : test4/views/index.jade
   create : test4/test
   create : test4/test/app.test.js
alfred@alfred-laptop:~/node$ cat test4/app.js 

/**
 * Module dependencies.
 */

var express = require('express');

var app = module.exports = express.createServer();

// Configuration

app.configure(function(){
  app.set('views', __dirname + '/views');
  app.use(express.bodyDecoder());
  app.use(express.methodOverride());
  app.use(express.compiler({ src: __dirname + '/public', enable: ['less'] }));
  app.use(app.router);
  app.use(express.staticProvider(__dirname + '/public'));
});

app.configure('development', function(){
  app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); 
});

app.configure('production', function(){
  app.use(express.errorHandler()); 
});

// Routes

app.get('/', function(req, res){
  res.render('index.jade', {
    locals: {
        title: 'Express'
    }
  });
});

// Only listen on $ node app.js

if (!module.parent) {
  app.listen(3000);
  console.log("Express server listening on port %d", app.address().port)
}

1
ขอบคุณฉันคิดว่านั่นคือสิ่งที่ฉันกำลังมองหา ฉันจะยอมรับมันทันทีที่ฉันมีโอกาสทดสอบ ไชโย
David Tang

4
และหากคุณไม่ต้องการให้มีตัวแปรvar listenerนั้นคุณสามารถใช้this.address().portในการapp.listen()โทรกลับได้
Andrei Stalbe

ลักษณะนี้เป็นอย่างไรใน Express 5.x
ไดโอจีเนส

2
นอกจากนี้คุณยังสามารถรับพอร์ตได้ทุกที่ในมิดเดิลแวร์: req.socket.address (). พอร์ต
jlguenego

เพียงเพิ่มสิ่งที่ @AndreiStalbe พูดคุณสามารถใช้this.address.port()แต่คุณไม่สามารถใช้สิ่งนั้นในฟังก์ชั่นลูกศร คุณจะต้องทำโรงเรียนเก่าapp.listen(8000, function () { console.log('http://localhost:' + this.address().port); }(ใช่ฉันรู้ว่า backticks ดีกว่า แต่ฉันไม่สามารถทำได้ในความคิดเห็นล้นสแต็ค)
WORMSS

65

ใน v3.0 ด่วน

/* No longer valid */
var app = express.createServer();
app.listen();
console.log('Server running on %s', app.address().port);

ไม่ทำงานอีกต่อไป! สำหรับ Express v3.0 คุณควรสร้างแอปและเซิร์ฟเวอร์ด้วยวิธีนี้:

var express = require('express');
var http = require('http');

var app = express();
var server = http.createServer(app);

app.get('/', function(req, res) {
    res.send("Hello World!");
});

server.listen(3000);
console.log('Express server started on port %s', server.address().port);

ฉันพบปัญหานี้ด้วยตัวเองและต้องการบันทึกไวยากรณ์ใหม่ การเปลี่ยนแปลงนี้และอื่น ๆ ใน Express v3.0 สามารถดูได้ที่https://github.com/visionmedia/express/wiki/Migrating-from-2.x-to-3.x


หรือคุณสามารถใช้วิธีการเดิมในการสร้างเซิร์ฟเวอร์ซึ่งยังใช้งานได้ ดูเหมือนว่าจะไม่มีทางเข้าถึงพอร์ต afterword อีกต่อไป อย่างไรก็ตามเนื่องจากคุณระบุพอร์ตด้วยตัวคุณเองในการเรียกไปยัง server.listen คุณไม่จำเป็นต้องใช้ server.address (). port เนื่องจากคุณสามารถใช้ค่าเดียวกับที่คุณส่งไปยัง server.listen
แมรี่แฮมลิน

(แม้ว่าฉันเพิ่งอ่านคู่มือการย้ายข้อมูลและดูว่าวิธีการสร้างแอปและเซิร์ฟเวอร์ที่คุณกล่าวถึงข้างต้นนั้นเป็นวิธีการที่ต้องการใหม่จริง ๆ )
แมรี่แฮมลิน

3
@MaryHamlin: สิ่งนี้มีประโยชน์หากคุณผ่าน0ไปserver.listen()ซึ่งในกรณีนี้จะมีการกำหนดหมายเลขพอร์ตแบบสุ่ม คุณอาจทำสิ่งนี้หากคุณใช้งานแอพ Express หลายรายการในเซิร์ฟเวอร์เดียวและคุณไม่ต้องการกำหนดหมายเลขพอร์ตด้วยตนเอง
เนท

app.listen()ยังส่งคืนอินสแตนซ์เซิร์ฟเวอร์ http
Vicary

23

ในเวอร์ชันปัจจุบัน (v0.5.0- ล่วงหน้า) พอร์ตดูเหมือนว่าจะมีอยู่เป็นคุณสมบัติบนวัตถุเซิร์ฟเวอร์ดูhttp://nodejs.org/docs/v0.4.7/api/net.html#server.address

var server = http.createServer(function(req, res) {
    ...
}

server.listen(8088);
console.log(server.address());
console.log(server.address().address);
console.log(server.address().port);

เอาท์พุท

{ address: '0.0.0.0', port: 8088 }
0.0.0.0
8088

22

ในกรณีที่คุณต้องการพอร์ตในขณะที่ทำการร้องขอและไม่มีแอพคุณสามารถใช้สิ่งนี้:

request.socket.localPort

17

หากคุณใช้ express คุณสามารถขอรับได้จากวัตถุคำขอ:

req.app.settings.port // => 8080 or whatever your app is listening at.

14

ฉันใช้วิธีนี้ Express 4:

app.listen(1337, function(){
  console.log('Express listening on port', this.address().port);
});

ด้วยการใช้สิ่งนี้ฉันไม่จำเป็นต้องใช้ตัวแปรแยกต่างหากสำหรับผู้ฟัง / เซิร์ฟเวอร์


1
คำตอบที่ดีที่สุด! หากคุณกำลังใช้ ES6 อย่าใช้ฟังก์ชั่นลูกศร thisจะไม่ได้กำหนด
Laxmana

9

ไม่จำเป็นต้องใช้โมดูล http

การนำเข้าเพิ่มเติมของhttpไม่จำเป็นใน Express 3 หรือ 4 การกำหนดผลลัพธ์ของlisten()ก็เพียงพอแล้ว

var server = require('express')();

server.get('/', function(req, res) {
  res.send("Hello Foo!");
});

var listener = server.listen(3000);
console.log('Your friendly Express server, listening on port %s', listener.address().port);
// Your friendly Express server, listening on port 3000

มีการทดสอบอีกครั้งใน Express 3.5.1 และ 4.0.0 การนำเข้าhttpไม่จำเป็น เมธอด Listen ส่งคืนออบเจ็กต์เซิร์ฟเวอร์ http https://github.com/visionmedia/express/blob/master/lib/application.js#L531


6

ด้วย node.js ล่าสุด (v0.3.8- ล่วงหน้า): ฉันตรวจสอบเอกสารตรวจสอบอินสแตนซ์ของเซิร์ฟเวอร์ที่ส่งคืนโดย http.createServer () และอ่านซอร์สโค้ดของ server.listen () ...

น่าเสียดายที่พอร์ตนั้นถูกเก็บไว้ชั่วคราวเป็นตัวแปรโลคัลและสิ้นสุดเป็นอาร์กิวเมนต์ในการเรียกไปยัง process.binding ('net'). bind () ซึ่งเป็นวิธีเนทีฟ ฉันไม่ได้ดูเพิ่มเติม

ดูเหมือนว่าไม่มีวิธีที่ดีไปกว่าการอ้างอิงถึงค่าพอร์ตที่คุณให้ไว้กับ server.listen ()


1
+1 และขอบคุณสำหรับการวิจัย ฉันยอมรับคำตอบของอัลเฟรดตั้งแต่เขาพบสิ่งที่ฉันกำลังมองหา แต่ฉันดีใจที่ฉันรู้ว่ามันไม่ได้อยู่ในแกนหลักโหนดตอนนี้
David Tang

5

วิธีที่ง่ายที่สุดในการแปลงจากรูปแบบเก่าเป็นรูปแบบใหม่ (Express 3.x) เป็นดังนี้:

var server = app.listen(8080);
console.log('Listening on port: ' + server.address().port);

ก่อน 3.x ทำงานเช่นนี้:

/* This no longer works */
app.listen(8080);
console.log('Listening on port: ' + app.address().port);


3

ฉันถามตัวเองด้วยคำถามนี้จากนั้นฉันก็มาหน้าคำแนะนำ Express 4.xเพื่อดูตัวอย่างนี้:

var server = app.listen(3000, function() {
   console.log('Listening on port %d', server.address().port);
});

2
แต่ฉันไม่รู้ว่าทำไม server.address () ที่อยู่เป็น 0.0.0.0 เสมอในเครื่องของฉัน (OSX)
Tien Do

สิ่งนี้ควรถูกเพิ่มไปยังคำตอบที่ยอมรับเนื่องจาก Express 4.0 ไม่ถือว่า app.listen () เป็นการดำเนินการแบบซิงโครนัสอีกต่อไปและคุณต้องเรียกใช้ listener.address () ในการเรียกกลับตอนนี้
RavenHursT

3

คุณสามารถรับหมายเลขพอร์ตได้โดยใช้server.address().port รหัสด้านล่าง:

var http = require('http');
var serverFunction = function (req, res) {

    if (req.url == '/') {
        console.log('get method');
        res.writeHead(200, { 'content-type': 'text/plain' });
        res.end('Hello World');
    }

}
var server = http.createServer(serverFunction);
server.listen(3002, function () {
    console.log('server is listening on port:', server.address().port);
});

3
var express = require('express');    
var app = express();
    app.set('port', Config.port || 8881);
    var server = app.listen(app.get('port'), function() {
        console.log('Express server listening on port ' + server.address().port); 
    });

เซิร์ฟเวอร์ Express กำลังฟังบนพอร์ต 8881


2

หากคุณไม่ได้กำหนดหมายเลขพอร์ตและคุณต้องการทราบว่าพอร์ตใดกำลังทำงานอยู่

let http = require('http');
let _http = http.createServer((req, res) => {
res.writeHead(200);
res.end('Hello..!')
}).listen();
console.log(_http.address().port);

FYI ทุกครั้งที่มันจะทำงานในพอร์ตที่แตกต่างกัน



-1

ใต้เซิร์ฟเวอร์ http แบบง่ายและวิธีรับพอร์ตการรับฟัง

var http = require("http");
             function onRequest(request, response) {
               console.log("Request received.");
               response.writeHead(200, {"Content-Type": "text/plain"});
               response.write("Hello World");
               response.end();
             }

             var server =http.createServer(onRequest).listen(process.env.PORT, function(){
            console.log('Listening on port '); //Listening on port 8888
        });

จากนั้นรับพอร์ตเซิร์ฟเวอร์โดยใช้:

console.log('Express server started on port %s', server.address().port);

-1
const express = require('express');                                                                                                                           
const morgan = require('morgan')
const PORT = 3000;

morgan.token('port', (req) => { 
    return req.app.locals.port; 
});

const app = express();
app.locals.port = PORT;
app.use(morgan(':method :url :port'))
app.get('/app', function(req, res) {
    res.send("Hello world from server");
});

app1.listen(PORT);

-2

วิธีที่ง่ายกว่าคือเพียงโทรหาapp.get('url')ซึ่งจะให้โปรโตคอลโดเมนย่อยโดเมนและพอร์ตแก่คุณ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.