concurrency - 使用 Clojure 进行服务器编程

标签 concurrency clojure

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

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

最佳答案

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))))

关于concurrency - 使用 Clojure 进行服务器编程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1735776/

相关文章:

oracle - 2 个用户同时运行一个存储过程 - 如果一次执行中的 DML 语句影响并行执行中的测试/条件会怎样?

javascript - 如何并发运行mongo脚本

sql - 可靠 SELECT + UPDATE 的事务与行标记

clojure - 如何解析Clojure中的URL参数?

clojure - 使用库化合物

java并发: multi-producer one-consumer

multithreading - 管理多进程 : What are the common strategies?

clojure - 用 Clojure 重写 Land of Lisp Wizard 游戏

javascript - 如何将 .js 文件包含到由 compojure 服务器提供的 html 文件中?

javascript - 如何发起和处理 POST 请求