2011-12-08 9 views
5

मैं Async प्रसंस्करण सर्वलेट एपीआई 3. यह काम कर रहा था के रूप में परिभाषित का उपयोग कर कोमेट चैट लागू करने के लिए कोशिश कर रहा था - बातचीत अवरोधित कर ली, तो मैं डिबग सर्वलेट बनाया है async हिस्सा केवल परीक्षण करने के लिए ।बिलाव 7 Async प्रसंस्करण में नाकाम रहने - एक ही अनुरोध संसाधित simultanously

@Override 
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
    log.debug("doGet called"); 
    int timeout = 30 + RandomUtils.nextInt(60); 
    String message = RandomStringUtils.randomAlphanumeric(50 + RandomUtils.nextInt(250)); 
    response.setHeader("Access-Control-Allow-Origin", "*"); 
    final AsyncContext context = request.startAsync(); 

    synchronized(items) { 
     items.add(new RequestItem(context, message, timeout)); 
    } 
    log.debug("doGet created request and finished"); 
} 

मैं कतार में अनुरोध आइटम डाल रहा हूँ, और वहाँ एक धागा चल रहा है, कि इसके बारे में आइटम निर्दिष्ट के बाद समय समाप्त मुद्रण संदेश लेने के लिए और AsyncContext के जवाब भेज देंगे, है:

यह मेरा तरीका है doGet । समस्या यह है कि थ्रेड को तब तक अवरुद्ध कर दिया जाता है जब तक AsyncContext का जवाब नहीं मिलता है। यह वही ब्राउज़र में 4 पृष्ठ लोड का अनुरोध करने के बाद अपने लॉग में देखा जा सकता है:

2011-12-08 13:56:36,923 DEBUG [my.servlet.TestAsyncServlet] doGet called 
2011-12-08 13:56:36,952 DEBUG [my.servlet.TestAsyncServlet] doGet created request and finished 
2011-12-08 13:57:39,934 TRACE [my.servlet.TestAsyncServlet] respond on item RequestItem [[email protected], message=zEQpATavzwFl6qIbBKve4OzIY9UUuZBwbqN1TC5KpU3i8LM9B6ChgUqaRmcT2yF, timeout=0] 
2011-12-08 13:57:39,962 DEBUG [my.servlet.TestAsyncServlet] doGet called 
2011-12-08 13:57:39,962 DEBUG [my.servlet.TestAsyncServlet] doGet created request and finished 
2011-12-08 13:58:53,949 TRACE [my.servlet.TestAsyncServlet] respond on item RequestItem [[email protected], message=pKHKC632CPIk7hGLV0YqCbQl1qpWIoyNv5OWCp21bEqoni1gbY79HT61QEUS2eCjeTMoNEwdqKzCZNGgDngULysSzVdzFTnQQ5cQ8JvcYnp1pLVqGTueJPWnbRdUuO, timeout=0] 
2011-12-08 13:58:53,960 DEBUG [my.servlet.TestAsyncServlet] doGet called 
2011-12-08 13:58:53,960 DEBUG [my.servlet.TestAsyncServlet] doGet created request and finished 
2011-12-08 13:59:36,954 TRACE [my.servlet.TestAsyncServlet] respond on item RequestItem [[email protected], message=43FPeEUZWBLqgkAqS3WOFMiHUMVvx6o4jNqWLx8kUvwxqJqpOZyGCtiIcr7yw, timeout=0] 
2011-12-08 13:59:36,999 DEBUG [my.servlet.TestAsyncServlet] doGet called 
2011-12-08 13:59:36,999 DEBUG [my.servlet.TestAsyncServlet] doGet created request and finished 
2011-12-08 14:00:34,957 TRACE [my.servlet.TestAsyncServlet] respond on item RequestItem [[email protected], message=r69Y4NQsyR1vj0kzUlHssic2x1Yrr6T09IGKjWAH1E6Lz4VhFTy9dQHi5CPeTObyjLLBDlCLEDfiyMUnVkVIEgYG7r47Ak4w30RklhzdEi9nthqdfNkry6nyjircsFPX534NqWjI1LwsrGq5nOa3ZYtfjfPVpGlk4KDmWP11L53YntO3GmptZPKa50gcqj9i, timeout=0] 

यह देखने के लिए है के रूप में, अगले doGet विधि कहा जाता है के बाद ही पिछले अनुरोध है (सैद्धांतिक रूप से अतुल्यकालिक) जवाब दे दिया। तो पूरी एसिंक चीज बिल्कुल काम नहीं कर रही है! और यहां web.xml घोषणा है:

<servlet> 
    <servlet-name>TestAsyncServlet</servlet-name> 
    <servlet-class>my.servlet.TestAsyncServlet</servlet-class> 
    <async-supported>true</async-supported> 
    </servlet> 
    <servlet-mapping> 
    <servlet-name>TestAsyncServlet</servlet-name> 
    <url-pattern>/test-async</url-pattern> 
    </servlet-mapping> 

मैं इंटरनेट पर पाया जाने वाला सब कुछ कर रहा हूं। मुझे गलती की जगह नहीं दिखती है। मुझे servlet.xml में कॉन्फ़िगरेशन के लिए कुछ खास नहीं मिला है। तो सवाल यह है कि यह क्यों काम नहीं कर रहा है?

उत्तर

5

ठीक है, शोध के हिस्से के रूप में मैंने परीक्षण प्रोग्राम लिखा है जो टोमकैट से गुणा कनेक्शन खोलता है और एसिंक सर्वलेट पर जीईटी/पोस्ट करता है। मैं डिबग है और परीक्षण के परिणाम आदि की बेहतर दृश्यता के लिए मेरी server.xml विन्यास, सीमित थ्रेड पूल फिर से जांचा अब कनेक्टर की मेरी विन्यास कि तरह लग रहा है:

<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" 
       minProcessors="3" 
       maxProcessors="8" 
       maxThreads="20" 
       connectionTimeout="150000" 
       asyncTimeout="150000" /> 

और यह काम कर रहा है! मैं NIO का उपयोग कर परीक्षण किया है और एक बार 1000 कनेक्शन बनाया है, और उन सभी को एक बार में संसाधित कर ली।

हालांकि, प्रभाव मैं का वर्णन किया है, अभी भी ब्राउज़र में मौजूद है। जब मैं 10 टैब पर सर्वलेट लोड करने का प्रयास करता हूं, तो पहले लोड से पहले लोड हो जाता है। ऐसा लगता है कि ब्राउज़र का व्यवहार होता है, सर्वर पर कुछ भी अवरुद्ध नहीं होता है। जब मैंने 3 ब्राउज़र खोले (फ़ायरफ़ॉक्स, क्रोम, ओपेरा) मुझे एक बार में 3 कनेक्शन संसाधित हुए हैं।

तो, सर्वलेट एपीआई 3.0 में परिभाषित एसिंक्रोनस प्रोसेसिंग टॉमकैट 7 पर काम करता है, हालांकि, इसे प्रोग्राम में कई टैब के साथ अपने प्रोग्राम के साथ परीक्षण किया जाना चाहिए ... कई टैब में सीओएमईटी चैट का परीक्षण उम्मीद के अनुसार भी काम नहीं कर सकता है। हालांकि, वास्तविक जीवन उदाहरण में एक कंप्यूटर केवल एक कनेक्शन खुल जाएगा। और, ब्राउज़र का व्यवहार किसी भी सर्वर की गलती नहीं है।

संपादित बसंत MVC समाधान वेब अनुप्रयोग में शामिल किया गया था, async प्रसंस्करण मोड बंद कर दिया गया था (web.xml से पैरामीटर को नजरअंदाज कर दिया गया था)। हालांकि, async समर्थन मैन्युअल रूप से जोड़ना लाइन के माध्यम से स्थापित किया जा सकता:

request.setAttribute("org.apache.catalina.ASYNC_SUPPORTED", true); 
+0

अजीब क्रोम और फ़ायरफ़ॉक्स कई जीईटी अनुरोधों को क्रमबद्ध करने लगते हैं यदि यूआरएल समान है। सफारी हालांकि ऐसा नहीं करता है। – Mark

1

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

उदाहरण के लिए, यदि आप Fiddler जैसे उपकरण के साथ मैसेजिंग मैं उम्मीद थी आप निम्नलिखित देखना चाहते हैं को देखने के लिए इस प्रकार थे:

Browser -> Server [Time: 0] Request 
Server -> Browser [Time: 0.1] Async Response 
Server -> Browser [Timer: 4] Complete Response 
Browser shows page loaded. 

आप async बाहर ले तो मोड आप देखना चाहते हैं:

Browser -> Server [Time: 0] Request 
Server -> Browser [Time: 4] Response 
Browser shows page loaded. 

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

दूसरे शब्दों में, मुझे नहीं लगता कि आप कह सकते हैं सर्वर सही या बस ब्राउज़र के साथ लोड करके नहीं है। मैं फिडलर जैसे टूल को पकड़ूंगा और देख सकता हूं कि वास्तव में कौन से HTTP संदेश चल रहे हैं।

+0

यह वही ब्राउज़र कर रहा है, लेकिन करने के लिए मैं प्रलेखन से समझ चुके हैं अनुसार, सर्वर इस तरह से async अनुरोध को पूरा करने की उम्मीद है कि धागा जारी किया जाएगा, जबकि कनेक्शन अभी भी सक्रिय होगा। दूसरे शब्दों में, गैर-अवरुद्ध I/O का उपयोग करने के लिए। अन्यथा यह इतना समझ नहीं होगा। मैं jquery-stream के साथ समान कोड का उपयोग कर रहा था, लेकिन प्रभाव बिल्कुल वही था, यह डीबग करने के लिए केवल difficulter था। –

संबंधित मुद्दे