Làm cách nào để tắt một phiên bản ExpressJS theo chương trình để thử nghiệm?


106

Tôi đang cố gắng tìm cách tắt một phiên bản của Express. Về cơ bản, tôi muốn nghịch đảo của .listen(port)cuộc gọi - làm cách nào để khiến máy chủ Express NGỪNG nghe, giải phóng cổng và tắt sạch?

Tôi biết đây có vẻ như là một truy vấn kỳ lạ, vì vậy đây là bối cảnh; có thể có một cách khác để tiếp cận điều này và tôi đang nghĩ về nó một cách sai lầm. Tôi đang cố gắng thiết lập khung thử nghiệm cho ứng dụng socket.io/nodejs của mình. Đó là một ứng dụng một trang, vì vậy trong các tập lệnh thử nghiệm của tôi (tôi đang sử dụng Mocha, nhưng điều đó không thực sự quan trọng) Tôi muốn có thể khởi động máy chủ, chạy các thử nghiệm đối với nó và sau đó tắt máy chủ. Tôi có thể giải quyết vấn đề này bằng cách giả định rằng máy chủ được bật trước khi thử nghiệm bắt đầu hoặc bằng cách để một trong các thử nghiệm khởi động máy chủ và mọi thử nghiệm tiếp theo đều cho rằng nó hoạt động, nhưng điều đó thực sự lộn xộn. Tôi muốn để mỗi tệp thử nghiệm khởi động một phiên bản máy chủ với các cài đặt thích hợp và sau đó tắt phiên bản đó khi các bài kiểm tra kết thúc. Điều đó có nghĩa là không có sự phụ thuộc kỳ lạ nào để chạy thử nghiệm và mọi thứ đều sạch sẽ. Nó cũng có nghĩa là tôi có thể thực hiện thử nghiệm khởi động / tắt máy.

Vì vậy, bất kỳ lời khuyên về cách làm điều này? Tôi đã nghĩ đến việc kích hoạt các ngoại lệ theo cách thủ công để giảm nó xuống, nhưng điều đó có vẻ lộn xộn. Tôi đã tìm hiểu các tài liệu và nguồn Express, nhưng dường như không thể tìm thấy bất kỳ phương pháp nào có thể tắt máy chủ. Cũng có thể có một cái gì đó trong socket.io cho điều này, nhưng vì máy chủ socket chỉ được gắn vào máy chủ Express, tôi nghĩ điều này cần phải xảy ra ở lớp express.

Câu trả lời:


156

Mọi thứ đã thay đổi vì máy chủ express không còn kế thừa từ máy chủ http của nút. May mắn thay, app.listen trả về phiên bản máy chủ.

var server = app.listen(3000);

// listen for an event
var handler = function() {
  server.close();
};

23
Trong trường hợp thử nghiệm Mocha, khi bạn yêu cầu ('ứng dụng'), tôi mở rộng sang đối tượng ứng dụng: app.server = app.listen (3000); vì vậy sau này tôi có thể nói: var app = request ('./ app'); app.server.close ();
Jack Chi

2
khi kiểm tra máy chủ, kiểm tra github.com/visionmedia/supertest nó sẽ cho phép bạn kiểm tra w / o tung ra máy chủ thực tế
Lukas Liesis

Tôi cũng sẽ đề nghị bạn chuyển lệnh gọi lại đã thực hiện tới server.close()nếu gọi nó từ bên trong hook.
Ullauri

Lưu ý: Có sự khác biệt lớn giữa 'ứng dụng', là phiên bản Ứng dụng Express và giá trị trả về của 'app.listen', là phiên bản Máy chủ HTTP gốc cơ bản có phương thức 'đóng'. @JackChi đã gợi ý về điều này ở trên.
ajxs

Điều này có gây ra sự cố với các ổ cắm máy khách đang mở bị bỏ ngỏ không?
Cameron Tacklind

18

Sử dụng app.close(). Ví dụ đầy đủ:

var app = require('express').createServer();
app.get('/', function(req, res){
  res.send('hello world');
});
app.get('/quit', function(req,res) {
  res.send('closing..');
  app.close();
});
app.listen(3000);

Gọi app.close()bên trong cuộc gọi lại khi kiểm tra kết thúc. Nhưng hãy nhớ rằng tiến trình vẫn đang chạy (mặc dù nó không còn lắng nghe nữa).

Nếu sau đó, bạn cần kết thúc quá trình, hãy gọi process.exit(0).

Liên kết:

app.close: http://nodejs.org/docs/latest/api/http.html#server.close (áp dụng tương tự cho)

process.exit: http://nodejs.org/docs/latest/api/process.html#process.exit


1
Hoàn hảo, chính xác những gì tôi đang tìm kiếm. Tôi đoán tôi không tìm thấy nó trong Express vì họ đang mở rộng máy chủ http nút lõi, điều mà tôi hoàn toàn không hiểu. Cảm ơn!
thu hút

Cảm ơn Srijan, mà đã giúp tôi quá
Adam Hopkinson

Điều này có còn đúng không? express.createServer là dấu như bị phản đối, và đưa ra một ứng dụng nói lỗi kế thừa không còn từ máy chủ http.js của
Frank Schwieterman

4
Đây không phải là hợp lệ kể từ khi nhanh 3.
gprasant

4
Để lộ một URL để đóng một máy chủ như thế này không phải là một ý kiến ​​hay của IMHO.
shime

2

Tôi đã trả lời một biến thể của "cách chấm dứt máy chủ HTTP" nhiều lần trên các các kênh hỗ trợ. Rất tiếc, tôi không thể giới thiệu bất kỳ thư viện hiện có nào vì chúng đang thiếu theo cách này hay cách khác. Kể từ đó, tôi đã tập hợp một gói (tôi tin rằng) đang xử lý tất cả các trường hợp dự kiến ​​chấm dứt máy chủ HTTP duyên dáng.

https://github.com/gajus/http-terminator

Lợi ích chính của http-terminator là:

  • nó không có API Node.js khỉ vá
  • nó ngay lập tức phá hủy tất cả các ổ cắm mà không có yêu cầu HTTP đính kèm
  • nó cho phép hết thời gian chờ đến các ổ cắm với các yêu cầu HTTP đang diễn ra
  • nó xử lý đúng các kết nối HTTPS
  • nó thông báo cho các kết nối bằng cách sử dụng chức năng giữ mạng rằng máy chủ đang tắt bằng cách thiết lập kết nối: đóng tiêu đề
  • nó không chấm dứt quá trình Node.js

Cách sử dụng với Express.js:

import express from 'express';
import {
  createHttpTerminator,
} from 'http-terminator';

const app = express();

const server = app.listen();

const httpTerminator = createHttpTerminator({
  server,
});

await httpTerminator.terminate();


-1

Bạn có thể dễ dàng thực hiện việc này bằng cách viết một tập lệnh bash để khởi động máy chủ, chạy thử nghiệm và dừng máy chủ. Điều này có lợi thế là cho phép bạn đặt bí danh cho tập lệnh đó để chạy tất cả các thử nghiệm của bạn một cách nhanh chóng và dễ dàng.

Tôi sử dụng các tập lệnh như vậy cho toàn bộ quá trình triển khai liên tục của mình. Bạn nên xem Quy trình làm việc Dead Simple Git của Jon Rohan để biết một số thông tin chi tiết về điều này.


2
Điều này sẽ hiệu quả, nhưng tôi muốn một giải pháp không có bash nếu có thể. Có thể đó là một tùy chọn ngu ngốc, nhưng tôi muốn khởi động / dừng máy chủ từ ngữ cảnh thử nghiệm vì nó giúp dễ dàng hơn khi viết các thử nghiệm dành riêng cho máy chủ + thử nghiệm khởi động / tắt máy. Thêm vào đó, nó không giới thiệu việc phải chạy các bài kiểm tra liên quan đến máy chủ thông qua một tập lệnh riêng biệt.
thu hút

Tại sao bạn viết các bài kiểm tra môi trường cụ thể? Có lẽ tôi sai, nhưng điều này đánh giá tôi là một hành vi tồi tệ. Tôi sẽ cố gắng duy trì môi trường không phù hợp với thử nghiệm của bạn, vì bạn muốn các thử nghiệm của mình hoạt động trong nhóm của bạn bất kể môi trường phát triển của họ.
Josh Smith

Tôi không làm bất cứ điều gì dành riêng cho môi trường ở đây, tôi không nghĩ vậy. Sẽ có một số tùy chọn khởi động khác nhau cho máy chủ (như đọc tùy chọn cấu hình từ tệp, trạng thái tải từ kho dữ liệu, v.v.) mà sẽ rất tuyệt nếu thử nghiệm trong cùng một khuôn khổ, tôi thử nghiệm mọi thứ khác. Tôi cũng muốn có các bài kiểm tra, chẳng hạn như tắt máy chủ, đưa nó hoạt động trở lại và đảm bảo rằng nó không bị mất trạng thái trong quá trình này. Điều đó dễ dàng hơn nếu tôi có thể làm điều đó theo chương trình từ nút hơn là có mã thử nghiệm trong bash.
drawww

Bạn sẽ không đặt mã thử nghiệm của mình trong chính bash. Bạn chỉ cần khởi động máy chủ và chạy các bài kiểm tra từ tập lệnh, giống như bạn sẽ tự thực hiện trên dòng lệnh. Không có ma thuật đặc biệt thực sự ở đó.
Josh Smith
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.