2009-11-14 2 views
14

क्लोजर में 10k कनेक्शन इको सर्वर को कैसे कार्यान्वित करें?क्लोजर

clojure.contrib.server-socket उत्तर नहीं है क्योंकि यह प्रत्येक कनेक्शन के लिए एक नया ओएस थ्रेड क्रेट करता है।

+2

क्या आप c10k समस्या का जिक्र कर रहे हैं? http://www.kegel.com/c10k.html –

+0

मैंने इसे पढ़ा, हां, और मुझे उत्सुकता है कि यह इस दिलचस्प भाषा में कैसे लागू किया जाएगा। ध्यान दें कि क्लोजर अपनी समवर्ती क्षमताओं का बहुत अधिक विज्ञापन करता है। – Roskoto

उत्तर

29

क्लोजर के बारे में सबसे अच्छी बात यह है कि आपके पास netty जैसे जेवीएम के लिए इन सभी महान पुस्तकालय हैं, जो अत्यधिक अनुकूलित, कॉन्फ़िगर करने योग्य और अच्छी तरह से सोचा जाता है। इस तरह कुछ आपको जाना चाहिए:

(ns netty 
    (:gen-class) 
    (:import 
    [java.net InetSocketAddress] 
    [java.util.concurrent Executors] 
    [org.jboss.netty.bootstrap ServerBootstrap] 
    [org.jboss.netty.channel Channels ChannelPipelineFactory 
           SimpleChannelHandler] 
    [org.jboss.netty.channel.socket.nio NioServerSocketChannelFactory] 
    [org.jboss.netty.buffer ChannelBuffers])) 

(declare make-handler) 

(defn start 
    "Start a Netty server. Returns the pipeline." 
    [port handler] 
    (let [channel-factory (NioServerSocketChannelFactory. 
          (Executors/newCachedThreadPool) 
          (Executors/newCachedThreadPool)) 
     bootstrap (ServerBootstrap. channel-factory) 
     pipeline (.getPipeline bootstrap)] 
    (.addLast pipeline "handler" (make-handler)) 
    (.setOption bootstrap "child.tcpNoDelay", true) 
    (.setOption bootstrap "child.keepAlive", true) 
    (.bind bootstrap (InetSocketAddress. port)) 
    pipeline)) 

(defn make-handler 
    "Returns a Netty handler." 
    [] 
    (proxy [SimpleChannelHandler] [] 
    (channelConnected [ctx e] 
     (let [c (.getChannel e)] 
     (println "Connected:" c))) 

    (channelDisconnected [ctx e] 
     (let [c (.getChannel e)] 
     (println "Disconnected:" c))) 

    (messageReceived [ctx e] 
     (let [c (.getChannel e) 
      cb (.getMessage e) 
      msg (.toString cb "UTF-8")] 
     (println "Message:" msg "from" c))) 

    (exceptionCaught 
     [ctx e] 
     (let [throwable (.getCause e)] 
     (println "@exceptionCaught" throwable)) 
     (-> e .getChannel .close)))) 
+3

धन्यवाद! मैंने यहां एक सरल लीनिंग परियोजना प्रस्तुत की है: https://github.com/cymen/clojure-netty – Cymen

+1

मैं इस सर्वर को एक संदेश कैसे भेजूं? – vemv

+1

@vemv मैंने सार्वजनिक नेटटी का उपयोग करने के लिए जिथब प्रोजेक्ट का उपयोग करने के लिए रेपो को अपडेट किया है और सर्वर को संदेश भेजने का एक उदाहरण जोड़ा है। – Cymen