2012-12-19 34 views
27

मेरे पास एक वेबपैप है जिसके लिए टॉमकैट 7 वेब सॉकेट के उपयोग की आवश्यकता है।टॉमकैट वेबसॉकेट सर्बलेट और Google गिइस

गूगल Guice के साथ इस webapp सभी मानक सर्वलेट्स ( javax.servlet.http.HttpServlet का विस्तार उन) अच्छी तरह से (और सही ढंग से) काम में

  1. @Singleton
  2. साथ सर्वलेट को सजाने की घोषणा & निजी Provider के लिए MyHandler उदाहरण एक सेटर जो इंजेक्शन
  3. के लिए चिह्नित किया गया है @Inject
  4. साथ सर्वलेट के निर्माता को सजाने उत्पन्न: Guice संचालकों मैं बस के साथ मेरी सर्वलेट काम करने के लिए

उपरोक्त बिंदुओं का प्रदर्शन करने के लिए उदाहरण:

@Singleton 
public class MyServlet extends HttpServlet { 

    private Provider<MyHandler> myHandler; 

    @Inject 
    MyServlet() { 
    } 

    @Override 
    protected void service(..) throws ServletException { ... } 

    @Inject 
    public void setMyHandler(Provider<MyHandler> myHandler) { 
     this.myHandler = myHandler; 
    } 

    ... 
} 

WebSocketServlet से myHandler नामक एक ही गुइस हैंडलर को कैसे कॉल किया जा सकता है?

मैं मानक सर्वलेट उपयोग मामले में समान शैली को अपनाने नहीं कर सकता क्योंकि मानक सर्विसलेट के मामले में सिंगलटन सर्वलेट होने के बजाय, प्रत्येक वेबसाकेट संचार परिणाम MessageInbound तक विस्तारित उदाहरण में; तो संदेश विधि उदाहरण के भीतर MyHandler पर कॉल करने वाली उपयुक्त विधि को विधि (उदा। onOpen या onClose) से कॉल किया जाता है; HttpServlet उदाहरण के भीतर MyServlet के रूप में एक विधि से नहीं।

मैंने क्या प्रयास किया? मैंने कुछ (अवधारणात्मक रूप से गलत) समाधानों को आजमाया जैसे कि वेबस्केट-सर्वलेट के हैंडलर को MessageInbound इंस्टेंस के भीतर से कॉल करना; निश्चित रूप से गुइस स्टैक ट्रेस को कम करने वाली समस्याओं को स्कॉइंग करने के परिणामस्वरूप। यह अवधारणा सही ऐसा करने का तरीका क्या है?

+0

यदि मैं आपको समझता हूं, तो आप WebSocketServlet # createWebSocketInbound ओवरराइड करते हैं जहां आप MessageInbound का एक नया उदाहरण बनाते हैं? यदि यह सत्य है, तो बस गिसिस को आपके लिए संदेशइनबाउंड बनाने दें (यदि आवश्यक हो तो इंजेक्ट की गई सहायता करें)। एकमात्र समस्या जो मैं देखता हूं वह http अनुरोध/प्रतिक्रियाओं के दायरे के साथ है क्योंकि चूहे फ़िल्टर ट्रैक रखने के लिए थ्रेड स्थानीय का उपयोग करता है। लेकिन इसे मुआवजा दिया जा सकता है। क्या मैंने सही तरीके से आपका अनुसरण किया? –

+0

आपकी टिप्पणी के लिए धन्यवाद, लेकिन मुझे इस भाग को समझ में नहीं आया: "तो बस गिसिस को आपके लिए संदेशइनबाउंड बनाने दें (यदि आवश्यक हो तो इंजेक्ट की गई सहायता करें)" –

उत्तर

1

अद्यतन:

कैसे आप Guice का उपयोग ठीक है। चूंकि MessageInbound का केवल एक विशेष उपयोग है AbstractGuiceWebSocketServlet की तरह किसी भी चीनी अनावश्यक है। प्रदाता ChatLogHdlr और फिर मैन्युअल निर्माण कर रहा है ठीक है। लेकिन आप एओपी समर्थन खो देते हैं। यदि इसकी आवश्यकता है तो आप सहायक इंजेक्ट करना चाहेंगे। लेकिन अभी के लिए यह ठीक है।

एक तरफ नोट पर, सेटर इंजेक्शन के बजाय निर्माण इंजेक्शन का उपयोग करें।

मैंने तुरंत देखा कि समस्या क्या है। यह गुइस नहीं है बल्कि आप गुइस-पर्सिस्ट का उपयोग कैसे करते हैं। मैंने जीपी का बहुत उपयोग नहीं किया और अभी भी आदरणीय वार्प-पर्सिस्ट का उपयोग करें। आप PersistService सुई शुरू करने के लिए Guice-जारी रहती है की जरूरत है

  1. : लेकिन मैं अपने कोड में कैसे आप का उपयोग Guice-जारी रहती है के साथ 2 समस्याओं को देखते हैं। यह WIKI उदा।

    public class PocWebApp extends GuiceServletContextListener { 
    
    @Inject 
    PersistService ps; 
    
    @Override 
    protected Injector getInjector() { 
        Injector injector = Guice.createInjector(new ServletModule() { 
    
         @Override 
         protected void configureServlets() { 
          install(new JpaPersistModule("DesktopPU")); 
          serve("/socket/main/").with(MainSocket.class); 
         } 
    
        }); 
        injector.injectMembers(this); 
        return injector; 
    } 
    
    @Override 
    public void contextInitialized(ServletContextEvent servletContextEvent) { 
        super.contextInitialized(servletContextEvent); 
        ps.start(); 
    } 
    } 
    
  2. PersistFilter बेकार के रूप में केवल पहली बार WebSocket गर्त फिल्टर जाना होगा लेकिन बाद के सभी संचार फिल्टर गर्त जाना नहीं होगा। टीट्रॉन का उपयोग केवल @ ट्रान्सैक्शनल (सत्र-प्रति-लेनदेन) के आसपास जाने का तरीका है।

विषय से संबंधित नहीं:

कितने उपयोगकर्ताओं आप का समर्थन करना चाहते हैं? यदि यह कट्टर चैट सर्वर होने जा रहा है तो मैं इसके बजाय नेटटी का उपयोग करूंगा लेकिन यह कुछ और शामिल है। इस पाया Googling:

http://comoyo.github.com/blog/2012/07/30/integrating-websockets-in-netty/

मूल जवाब:

तो इस शैली के बारे में एक सवाल है?

वेबसाकेट्स! = सर्वलेट्स। अगर उन्हें थोड़ा अलग शैली की आवश्यकता होती है तो कुछ भी गलत नहीं है। मैं भी याद दिलाना पसंद करूंगा कि मैं वेनिला सर्वलेट से निपट नहीं रहा हूं।

कुछ टिप्पणियों:

WebSocketServlet कुछ खास नहीं है। आप आसानी से गुइस-सर्वलेट के साथ इसका उपयोग कर सकते हैं। उदा .:

@Singleton 
public class FooGuiceWebSocketServlet extends WebSocketServlet {...} 

और फिर के रूप में

serve("/foo").with(FooGuiceWebSocketServlet.class); 

अब, MessageInbound खास है कि के रूप में सभी बिलाव द्वारा नियंत्रित किया जाता के रूप में आप विस्तार से बताया यह refernce। MessageInbound वेबसाकेट scoped है। अब गुइस को इस दायरे के बारे में कोई जानकारी नहीं है और इसे इस तरह से छोड़ने का अर्थ हो सकता है।

स्टार्टर्स के लिए मैं सुनिश्चित करता हूं कि संदेश इनबाउंड गुइस द्वारा बनाया गया है। इस तर्ज पर कुछ:

@Singleton 
public class ExampleWebSocketServlet extends AbstractGuiceWebSocketServlet { 

    @Override 
    public Class<? extends StreamInbound> serveWith() { 
     return Foo.class; 
    } 

    public static class Foo extends MessageInbound { 

    @Inject GuiceCreatedAndInjected bar; 

    @Override 
    protected void onBinaryMessage(ByteBuffer byteBuffer) throws IOException { 
     // do nothing 
    } 

    @Override 
    protected void onTextMessage(CharBuffer charBuffer) throws IOException { 
     // this getSwOutbonds() is not very friendly to testing 
     getWsOutbound().writeTextMessage(bar.echo(charBuffer)); 
    } 

    } 
} 

कहाँ

public abstract class AbstractGuiceWebSocketServlet extends WebSocketServlet { 

    @Inject Injector injector; 

    @Override 
    protected StreamInbound createWebSocketInbound(String subProtocol, HttpServletRequest request) { 
     return injector.getInstance(serveWith()); 
    } 

    public abstract Class<? extends StreamInbound> serveWith(); 

} 

आप जरूरत के मुताबिक यहां से उच्च कपोल-कल्पना और/या scopings पर जा सकते हैं। मुझे विशेष रूप से #getWsOutbound() पसंद नहीं है क्योंकि यह परीक्षण में बाधा डालता है।

बस संतुष्ट होने तक शैली में सुधार करना जारी रखें। कहें कि आपको और मदद चाहिए (उत्तर संशोधित करेगा)।

+0

आपके उत्तर के लिए धन्यवाद। समस्या यह सबसे आसान मामला है; मुझे कनेक्शन और आविष्कार कनेक्शन आईडी का ट्रैक रखने की आवश्यकता है; [github] (https://github.com/jvzammit/wspoc) पर समस्या को दोहराने के लिए एक सरल सबूत-अवधारणा पर एक नज़र डालें, और [MainSocket.java] में मेरी 'createWebSocketInbound' विधि (https: // github.com/jvzammit/wspoc/blob/master/wspoc/poc-web/src/main/java/com/cif/dt/app/websocket/MainSocket.java) जहां मैंने प्रत्येक खुले websocket कनेक्शन में 'क्लाइंटनो' सेट किया है । मैं इस संरचना में कहां करता हूं आप सुझाव देते हैं? –

+0

मैंने आपकी अनुशंसित संरचना को [अवधारणा के सबूत] (https://github.com/jvzammit/wspoc) पर लागू किया और ठीक उसी तरह 'java.lang.IleglegalStateException' पहले जैसा मिला। –

+0

अद्यतन उत्तर, उम्मीद है कि यह आपकी समस्या हल करता है। –

0

मुझे समझ में नहीं आया कि आप क्या हासिल करने की कोशिश कर रहे हैं। मैं गुइस में एओपी समर्थन की तलाश करूंगा। ऐसा लगता है कि आपको संदेश कीबाउंड सबक्लास 'उदाहरण के कुछ तरीकों में इस्तेमाल होने से पहले MyHandler सेट (इंजेक्ट) की आवश्यकता है। एक पहलू ऐसा कर सकता है।

हालांकि, एक प्रश्न पूछने की आवश्यकता है: (तत्कालकरण) नियंत्रण कहां है? यदि आपके टॉमकैट एप्लिकेशन कॉन्फ़िगरेशन में किसी प्रकार का प्रतिनिधिमंडल जोड़ने का कोई तरीका है, तो Guice MessageInbound उदाहरणों को "बढ़ा" सकता है, जो बदले में, उपयोग से पहले उचित मायहैंडलर सेट होगा। GitHub उदाहरण देखने के बाद