2016-08-22 8 views
8

से अधिक सर्वर तक पहुंचने के लिए मैं एक वेब अनुप्रयोग विकसित करता हूं। क्लाइंट साइड - जावास्क्रिप्ट/टाइपस्क्रिप्ट + एंगुलरजेएस सर्वर साइड - सी # - एएसपीनेट वेब एपीआई 2 होस्ट के रूप में आईआईएस एक्सप्रेस।एचटीपी पोस्ट अनुरोध एक बार

मैंने एक व्यापक समस्या देखी जिसमें पोस्ट आवश्यकताएं एक से अधिक बार सर्वर तक पहुंच गईं। उदाहरण के लिए, एक परिदृश्य जिसमें अनुरोध कई बार भेजे जाते हैं, एक विशिष्ट फ़ोल्डर ईमेल के लिए प्रत्येक अनुरोध 3 बार भेजा जाता है। मैं नेटवर्क टैब में तीन बार भेजे गए अनुरोध को भी देखता हूं।

public class mailsService extends ImailsService{ 

    static instance : ImailsService; 

    // Dictionary of folder -> emails 
    public Folders; 


    public mailsService(){ 
     var scope = this; 
     myInterval = setInterval(function(){ 
        // Making this request until getting a successful response - waiting for server to go up 
      scope.webService.get("url to get my own place").success(data => { 
       scope.myLocation = data; 
       scope.isLocationInit = true; 
       getAllMails(); 
       window.cleanInterval(myInterval); 
      }) 
     }, 3000); 
    } 

    // This function happen on it's own when running the client code. 
    // The service is a singleton therefore this code runs only once. 
    public getAllMails() { 
    if (!this.isLocationInit) 
     return; 
    var scope = this; 
    scope.webService.get("url to get all folders").then(reponse => { 
     var folders = response.data; 

     for (var i = 1; i <= folders.length; i ++){ 
       return scope.get("url to get the mails inside specific folder").then(initMails.bind(null, i)); 
     }}); 
    } 

    public initMails (folderId : number, response){ 
     mailsService.instance.Folders[folderId].push(response.data); 
    } 
} 

public class webService extends IwebService { 
    public get(url : string){ 
     return this.$http.get(url); 
    } 

    public post(url : string, data : any){ 
     return this.$http.post(url, data); 
    } 
} 


// Server side: 

// Cross-Origin requests 
[EnableCors(origins: "*", headers: "*", methods: "*")] 
public class MailsController : ApiController 
{ 
    private IMailsService _mailsService; 

    public MailsController(IMailsService service) 
    { 
     this._mailsService = service; 
    } 

    public IHttpActionResult GetAllFolders() 
    { 
     var result = _mailsService.GetAllFolders(); 
     if (result == null) 
      return BadRequest("..."); 

     return Ok(result); 
    } 

    public IHttpActionResult GetFolderEmails(int folderId) 
    { 
     var result = _mailsService.GetFolderEmails(folderId); 
     if (result == null) 
      return BadRequest("..."); 

     return Ok(result); 
    } 
} 

नियंत्रक फिटिंग विधि दो बार या उससे भी अधिक हिट करती है, हालांकि इसे क्लीएंड साइड कोड से केवल एक बार कहा जाता है।

क्या यह कुछ कॉन्फ़िगरेशन है? आईआईएस डरावनी चीज? मैं गंभीरता से नहीं जानता कि कहां दिखना शुरू करें।

+3

यह असंभव है कि यह आईआईएस या सर्वर पक्ष है। मैंने पहले ऐसा कुछ देखा है और यह पता चला है कि $ http.post को कॉल करने वाले जावास्क्रिप्ट ईवेंट को क्लिक ईवेंट से दो बार जोड़ा गया था। तो जब उपयोगकर्ता क्लिक किया गया, जावास्क्रिप्ट घटना दो बार निकाल दी गई, जिसके कारण सर्वर पर दो POSTs हुईं, भले ही कोड केवल ऐसा दिखता है जैसे यह एक बार होना चाहिए। जांचने के लिए, अपने ब्राउज़र देव उपकरण के नेटवर्क टैब को देखें और देखें कि कितने नेटवर्क अनुरोध हैं। यदि दो, जावास्क्रिप्ट पर ध्यान केंद्रित करें - $ http.post लाइन को तोड़ने के लिए ब्राउज़र देव उपकरण का उपयोग करें और पुष्टि करें कि वह पंक्ति कितनी बार हिट होती है। –

+0

कृपया जांचें कि आपका ब्राउज़र प्रीफलाइट अनुरोध कर रहा है या नहीं। :) प्रीफलाइट के बारे में और जानने के लिए कृपया यहां एक नज़र डालें [http://stackoverflow.com/questions/8685678/cors-how-do-preflight-an-httprequest) –

+0

मैंने नेटवर्क टैब की जांच की है और अनुरोध हैं कई बार भेजा गया। क्लाइंट साइड कोड निश्चित रूप से एक बार चल रहा है, यह नहीं पता कि ऐसा होने का कारण क्या हो सकता है। –

उत्तर

2

mailsService में, आप प्रत्येक 3 सेकंड में वेब सेवा को कॉल करने के लिए अंतराल टाइमर सेट करते हैं। क्या यह संभव है कि, जब तक प्रतिक्रिया वापस आ गई हो और पूरी प्रक्रिया पूरी हो गई है, टाइमर ने एक या दो बार टिक डाला है और फिर प्रक्रिया को ट्रिगर किया है? आप अंतराल को छोटे और लंबे मानों में बदलकर परीक्षण कर सकते हैं और देख सकते हैं कि यह सर्वर पर कॉल की संख्या को प्रभावित करता है या नहीं। जोखिम को कम करने के

एक तरह से getAllMails को कॉल करने से पहले अपनी सफलता कॉल बैक समारोह के बहुत शुरुआत में window.clearInterval कॉल करने के लिए, होगा:

scope.webService.get("url to get my own place").success(data => { 
    window.clearInterval(myInterval); 
    scope.myLocation = data; 
    scope.isLocationInit = true; 
    getAllMails(); 
} 

एक अन्य समाधान setInterval का उपयोग कर से बचने के लिए किया जाएगा। आप scope.webService.get निष्पादित कर सकते हैं और प्रतिक्रिया की प्रतीक्षा कर सकते हैं। त्रुटि के मामले में, आप थोड़ी देर बाद फिर से सेवा कहेंगे, setTimeout का उपयोग कर:

public mailsService() { 
    var scope = this; 
    (function callWebService() { 
     scope.webService.get("url to get my own place") 
      .success(data => { 
       scope.myLocation = data; 
       scope.isLocationInit = true; 
       getAllMails(); 
      }) 
      .error(data => { 
       setTimeout(callWebService, 3000); 
      }); 
    })(); 
} 

नोट: मैं टाइपप्रति से परिचित नहीं हूँ, इसलिए इसे लागू करने के लिए एक बेहतर तरीका हो सकता है।

+0

आपकी सलाह के लिए धन्यवाद, दूसरा दृष्टिकोण लिया! –

+0

आपका स्वागत है! – ConnorsFan

0

मेरे पास टिप्पणी सुविधा नहीं है, लेकिन मैं हमेशा जो करता हूं वह फॉर्म पोस्ट करने के बाद एक नया नया पृष्ठ लोड करता है, क्योंकि यदि उपयोगकर्ता ब्राउज़र के बैक बटन (वे अक्सर ऐसा करते हैं) को हिट करते हैं, तो आपका फॉर्म भेजा जाएगा फिर। यदि आप इसके बजाय एक नया पृष्ठ लोड करते हैं, तो आपका फॉर्म फिर से लोड नहीं होगा। सुनिश्चित नहीं है कि आपकी समस्या हमेशा होती है, परीक्षण के साथ भी, मुझे लगता है कि आपको अधिक कोड पोस्ट करने की आवश्यकता है।

+0

हाय, मैंने एक सेनेनारियो का पूरा प्रवाह जोड़ा जो इस समस्या का कारण बनता है। –

0

क्या यह सभी ब्राउज़रों में हो रहा है? मैंने हाल ही में एक खाली स्रोत विशेषता के साथ एक स्क्रिप्ट टैग देखा है क्योंकि फ़ायरफ़ॉक्स पृष्ठ को कई बार लोड करता है।

0

मैं आपके वेब एपीआई कोड में पोस्ट के लिए उम्मीदवार नहीं देखता हूं और न ही आपके जावास्क्रिप्ट में एक पोस्ट कॉल भी देखता हूं। क्या मैं कुछ भूल रहा हूँ?

आप उदाहरण के लिए उल्लेख किया है के रूप में, जिसमें एक परिदृश्य अनुरोध कई बार भेजा जाता है, एक विशिष्ट फ़ोल्डर ईमेल के लिए प्रत्येक अनुरोध भेज दिया जाता है 3 बार, मैं अपने getAllMails() विधि thats कहा जाता हो रही है कई बार यह सोचते हैं रहा हूँ।इस का कारण यह नीचे दी गई विधि में setInterval तर्क है:

public mailsService(){ 
     var scope = this; 
     myInterval = setInterval(function(){ 
        // Making this request until getting a successful response - waiting for server to go up 
      scope.webService.get("url to get my own place").success(data => { 
       scope.myLocation = data; 
       scope.isLocationInit = true; 
       getAllMails(); 
       window.cleanInterval(myInterval); 
      }) 
     }, 3000); 

    } 

वहाँ एक संभावित संभावना है कि इस कॉल के लिए कई बार किया जाएगा है - एक परिदृश्य में जहाँ पहले ही कॉल (0 सेकंड) scope.webService.get("url to get my own place") करने के लिए किया ले लिया पर विचार पूरा करने के लिए 6 सेकंड - सेट के अंतराल तर्क के कारण यह तीसरे और 6 वें सेकेंड में एजेक्स कॉल समाप्त हो जाएगा क्योंकि सेट इंटरवल अनुरोध के सफलता कॉलबैक के बाद ही मंजूरी दे दी गई है।

यदि setInterval के पीछे तर्क // Making this request until getting a successful response - waiting for server to go up पर टिप्पणी में है, तो मैं आपको एक अलग दृष्टिकोण के लिए जाने का सुझाव दूंगा।

मुझे यकीन नहीं है कि यह "सर्वर" नहीं होने पर आपका सर्वर rsponding क्या होगा, लेकिन यह मानते हुए कि यह उस परिदृश्य में कुछ त्रुटि कोड देता है (कहें, त्रुटि कोड -1), फिर अपनी त्रुटि कॉल में एक चेक करें वापस और यदि त्रुटि कोड "सर्वर ऊपर नहीं है" से संबंधित कुछ है, तो फिर उसी विधि को कॉल करें। कुछ ऐसा:

public mailsService(){ 
     var scope = this; 

     scope.webService.get("url to get my own place") 
      .then(function(data) { 
       scope.myLocation = data; 
       scope.isLocationInit = true; 
       getAllMails();  
      }, 
      function(ex) 
      { 
       if(ex.status === "-1") 
       { 
       //service seems to be 'not up', keep hitting the service 
       mailsService();  
       } 
      }); 
     } 
संबंधित मुद्दे