2015-01-15 14 views
5

Tôi có đoạn code sau trong Node.js trong một chức năng readFile:Tại sao phản hồi bị đóng và chưa kết thúc?

 res.setHeader("content-type", 'application/octet-stream'); 
     res.setHeader("Content-Disposition", 'attachment; filename="' + 'original' + '"' + "; filename*=UTF-8''" + 'original' + ""); 
     var readStream; 
     var exists = fs.existsSync(fullPath); 
      if (exists) { 
       callback(true); 
       readStream = fs.createReadStream(fullPath); 
       readStream.pipe(res); 
      } else { 
       callback(false); 
       return; 
      } 
       res.on('finish', function(){ 
         logger.info('response ending'); 
         readStream.close(); 
       }) 
       res.on('close', function(){ 
         logger.info('response close'); 
         readStream.close(); 
       }) 
       res.on('error', function(error){ 
         logger.info(error); 
         readStream.close(); 
       }) 

Đối với một số lý do, một số yêu cầu được phát ra sự kiện close, trong khi khác finish. Theo tôi hiểu, close được phát ra khi có sự cố.

Sự kiện đóng có thể kích hoạt từ 2 giây đến 2 phút. Trong một số ít trường hợp, không có số close và không có sự kiện nào được phát ra và tất cả yêu cầu bị "kẹt", chờ đợi phản hồi.

Điều gì có thể là lý do khiến một số yêu cầu thành công và một số yêu cầu khác không thành công?

EDIT

Làm thế nào tôi có thể biết lý do tại sao một sự kiện gần đã phát ra? Có phải là một vấn đề của khách hàng hoặc một lỗi trong ứng dụng của tôi không?

+0

Bạn thử nghiệm điều này như thế nào? –

+0

@JoshC. Khách hàng của tôi gửi cho tôi yêu cầu (Tôi đang sử dụng mô-đun thể hiện). Tôi nhận thấy rằng ứng dụng của tôi đang nhận được 'readStream.pipe (res);'. Sau 2 giây đến 2 phút, sự kiện đóng sẽ được kích hoạt. –

Trả lời

1

tôi nghĩ điều này xuất phát từ giao thức HTTP HTTP. có một tùy chọn cho giữ sống. nếu điều này được sử dụng thì kết nối có thể được tái sử dụng cho các yêu cầu khác nhau.

bạn tắt tính năng này với res.set("Connection", "close"); kiến ​​kiểm tra lại.

2

nếu có finish thì tất cả đều bình thường, nhưng nếu có close thì có thể là do bất cứ điều gì. Tôi đã thử mã sau đây để khai báo sự kiện của bạn, trước khi đường ống được hoàn thành.

1. `res.emit('close');` And 
2. `readStream.close();` 

Bây giờ, cái đầu tiên ở đây phát ra một cách rõ ràng sự kiện đóng và sự kiện thứ hai đóng luồng readStream được tạo đường ống. cả hai phát biểu này đều gây ra việc kích hoạt res.on('close'), nhưng tôi thực sự không thể tìm ra lý do cho số close.

tôi không thể chắc chắn nếu nó là một lỗi máy chủ hoặc khách hàng lỗi, nhưng có thể có lý do sau:

  1. res.emit('close'); phát ra một cách rõ ràng sự kiện gần.

  2. đã xảy ra sự cố với nguồn đường ống. (ví dụ trong trường hợp trên # 2 readStream đã được đóng) trong trường hợp này sẽ mất nhiều thời gian hơn một chút so với các lý do còn lại.

  3. Mạng đi xuống sau khi phản ứng cử được bắt đầu

  4. khách hàng cũng có thể gây ra các sự kiện gần để kích hoạt, nếu nó yêu cầu dữ liệu và sau đó sau đó khách hàng đã không có mặt để nhận dữ liệu.

lý do có thể là bất kỳ điều gì khiến cho phản hồi không hoàn thành.

1

tôi muốn kết thúc phản hồi của bạn khi sự kiện đóng và kết thúc được gọi thay vì đóng readStream.

res.setHeader("content-type", 'application/octet-stream'); 
    res.setHeader("Content-Disposition", 'attachment; filename="' + 'original' + '"' + "; filename*=UTF-8''" + 'original' + ""); 
    var readStream; 
    var exists = fs.existsSync(fullPath); 
     if (exists) { 
      callback(true); 
      readStream = fs.createReadStream(fullPath); 
      readStream.pipe(res); 
     } else { 
      callback(false); 
      return; 
     } 
      res.on('finish', function(){ 
        logger.info('response ending'); 
        readStream.close(); // This closes the readStream not the response 
        res.end('FINISHED'); // Ends the response with the message FINISHED 

      }) 
      res.on('close', function(){ 
        logger.info('response close'); 
        readStream.close(); // This closes the readStream not the response 
        res.end('CLOSED'); // Ends the response with the message CLOSED 

      }) 
      res.on('error', function(error){ 
        logger.info(error); 
        readStream.close(); // This closes the readStream not the response 
        res.end(error); // Ends the response with ERROR 
      }) 

Phản hồi không được đóng vì bạn đóng readStream để đóng riêng ReadStream và không trả lời. Để hoàn thành hoặc kết thúc việc sử dụng câu trả lời res.end().

tham khảo: http://nodejs.org/api/http.html#http_event_close_1 http://nodejs.org/api/http.html#http_response_end_data_encoding

Hope this helps.

Các vấn đề liên quan