【问题标题】:Server programming with Clojure使用 Clojure 进行服务器编程
【发布时间】:2010-12-16 16:27:45
【问题描述】:

如何在 Clojure 中实现 10k 连接回显服务器?

clojure.contrib.server-socket 不是答案,因为它为每个连接创建一个新的操作系统线程。

【问题讨论】:

  • 你指的是c10k问题吗? kegel.com/c10k.html
  • 我读过它,是的,我很好奇它将如何用这种有趣的语言实现。请注意,clojure 经常宣传其并发能力。

标签: concurrency clojure


【解决方案1】:

Clojure 的优点在于您拥有所有这些用于 JVM 的出色库,例如 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))))

【讨论】:

  • 谢谢!我在这里放了一个简单的 leiningen 项目:github.com/cymen/clojure-netty
  • 如何向该服务器发送消息?
  • @vemv 我已经更新了 repo 以使用 github 项目来使用公共网络,并添加了一个如何向服务器发送消息的示例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-03
  • 2014-11-26
  • 2019-11-20
  • 1970-01-01
  • 1970-01-01
  • 2015-09-24
  • 1970-01-01
相关资源
最近更新 更多