2009-11-14 63 views
14

如何在Clojure中實現10k連接回顯服務器?使用Clojure進行服務器編程

clojure.contrib.server-socket不是答案,因爲它爲每個連接創建一個新的操作系統線程。

+2

你指的是c10k問題? http://www.kegel.com/c10k.html – 2009-11-14 22:17:23

+0

我讀過,是的,我很好奇它是如何在這個有趣的語言中實現的。請注意,clojure廣泛宣傳其併發功能。 – Roskoto 2009-11-14 22:26:12

回答

29

關於Clojure的好處是你擁有所有這些優秀的庫,像JVM,如netty,這些JVM經過高度優化,可配置和深思熟慮。像這樣的東西應該讓你去:

(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

謝謝!我在這裏爲此提出了一個簡單的leiningen項目:https://github.com/cymen/clojure-netty – Cymen 2012-03-12 20:02:23

+1

如何向此服務器發送消息? – vemv 2013-03-16 19:25:08

+1

@vemv我已經更新了回購使用github項目來使用公共netty,並添加了一個如何發送消息到服務器的例子。 – Cymen 2013-03-22 13:51:42

相關問題