Java 互操作——Netty + Clojure

2024-04-15

我正在尝试通过 clojure 使用 netty。我可以启动服务器,但是它无法初始化接受的套接字。下面分别是错误消息和代码。有谁知道什么是/或可能是错误的?我相信问题在于(Channels/pipeline (server-handler)) Thanks.

错误信息

#<NioServerSocketChannel [id: 0x01c888d9, /0.0.0.0:843]>
Jun 6, 2012 12:15:35 PM org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink
WARNING: Failed to initialize an accepted socket.
java.lang.IllegalArgumentException: No matching method found: pipeline

项目.clj

(defproject protocol "1.0.0-SNAPSHOT"
  :description "Upload Protocol Server"
  :dependencies [
    [org.clojure/clojure "1.2.1"]
    [io.netty/netty "3.4.5.Final"]])

core.clj

(ns protocol.core
    (: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)))

(def policy
    "<content>Test</content>")


(defn server-handler
    "Returns netty handler."
    []
    (proxy [SimpleChannelHandler] []
        (messageReceived [ctx e]
            (let [ch (.getChannel e)]
                (.write ch policy)
                (.close ch)))

        (channelConnected [ctx e]
            (let [ch (.getChannel e)]
                (.write ch policy)
                (.close ch)))

        (exceptionCaught [ctx e]
            (let [ex (.getCause e)]
                (println "Exception" ex)
                (-> e .getChannel .close)))))

(defn setup-pipeline
    "Returns channel pipeline."
    []
    (proxy [ChannelPipelineFactory] []
        (getPipeline []
            (Channels/pipeline (server-handler)))))

(defn startup
    "Starts netty server."
    [port]
    (let [channel-factory (NioServerSocketChannelFactory. (Executors/newCachedThreadPool) (Executors/newCachedThreadPool))
          bootstrap (ServerBootstrap. channel-factory)]
        (.setPipelineFactory bootstrap (setup-pipeline))
        (.setOption bootstrap "child.tcpNoDelay" true)
        (.setOption bootstrap "child.keepAlive" true)
        (.bind bootstrap (InetSocketAddress. port))))

您的代码存在三个问题

  1. Java 与 vararg Channels.channel() 方法的互操作。 您可以创建一个通道处理程序向量并将其包装为(into-array ChannelHandler ..)

  2. 您不能将 String 对象直接写入 Netty Channel。 您必须先将字符串写入 ChannelBuffer,然后写入该缓冲区或使用 StringCodecHandler。

  3. 写入 Netty 通道是异步的,因此您无法立即关闭它。 您必须注册未来的侦听器并在完成后关闭通道。

这是工作代码。

  (ns clj-netty.core
   (:import (java.net InetSocketAddress)
            (java.util.concurrent Executors)
            (org.jboss.netty.bootstrap ServerBootstrap)
            (org.jboss.netty.buffer ChannelBuffers)
            (org.jboss.netty.channel Channels ChannelFutureListener ChannelHandler ChannelPipelineFactory SimpleChannelHandler)
           (org.jboss.netty.channel.socket.nio NioServerSocketChannelFactory)
           (org.jboss.netty.buffer ChannelBuffers)))


(def policy
  (ChannelBuffers/copiedBuffer
    (.getBytes "<content>Test</content>")))


(defn server-handler
  "Returns netty handler."
  []
  (proxy [SimpleChannelHandler] []
    (messageReceived [ctx e]
      (let [ch (.getChannel e)]
        (.addListener
          (.write ch policy)
          (ChannelFutureListener/CLOSE))))

    (channelConnected [ctx e]
      (let [ch (.getChannel e)]
        (.addListener
          (.write ch policy)
          (ChannelFutureListener/CLOSE))))

    (exceptionCaught [ctx e]
      (let [ex (.getCause e)]
        (println "Exception" ex)
        (-> e .getChannel .close)))))

(defn setup-pipeline
  "Returns channel pipeline."
  []
  (proxy [ChannelPipelineFactory] []
    (getPipeline []
      (let [handler (server-handler)]
        (Channels/pipeline (into-array ChannelHandler [handler]))))))



 (defn startup
      "Starts netty server."
      [port]
      (let [channel-factory (NioServerSocketChannelFactory. (Executors/newCachedThreadPool) (Executors/newCachedThreadPool))
            bootstrap (ServerBootstrap. channel-factory)]
        (.setPipelineFactory bootstrap (setup-pipeline))
        (.setOption bootstrap "child.tcpNoDelay" true)
        (.setOption bootstrap "child.keepAlive" true)
        (.bind bootstrap (InetSocketAddress. port))))

看一下Aleph https://github.com/ztellman/aleph(也使用 Netty)它可以使用漂亮的 Clojure API 以许多不同的协议构建客户端和服务器。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java 互操作——Netty + Clojure 的相关文章

  • 在 Clojure 中使用 http://foobar.mp3 重定向到 http://fizzbar.mp3

    我正在尝试以编程方式下载 mp3 文件这个 RSS 提要 http podcast menlo church feed 当我打开一个网址时 例如 http menlohurch podbean com mf feed 5gv2gb 1702
  • 为什么使用关键字或符号作为函数从地图中查找值有效?

    引用自Clojure 的乐趣 第 4 3 1 节 由于关键字是自我评估的并提供快速的相等性检查 因此它们几乎总是在映射键的上下文中使用 使用关键字作为映射键的一个同样重要的原因是它们可以用作函数 以映射作为参数来执行值查找 def popu
  • Clojure 中的相互递归定义

    如何在 Clojure 中进行相互递归定义 下面是 Scala 中使用递归定义查找素数的代码 val odds Stream Int cons 3 odds map 2 val primes Stream Int cons 2 odds f
  • 如何在 Clojure 中处理大型二进制数据?

    如何在 Clojure 中处理大型二进制数据文件 我们假设数据 文件大约为 50MB 小到足以在内存中处理 但不是简单的实现 以下代码正确地从小文件中删除 M 但它会抛出OutOfMemoryError对于较大的文件 如 6MB defn
  • netty 4.x.x 中的 UDP 广播

    我们需要使用 Netty 4 0 0 二进制文件通过 UDP 通道广播对象 Pojo 在 Netty 4 0 0 中 它允许我们仅使用 DatagramPacket 类来发送 UDP 数据包 此类仅接受 ByteBuf 作为参数 还有其他方
  • clojure 的 emacs slime-connect 版本不会查找 $CLASSPATH

    我需要将 clojure 函数与 slime connect 一起使用 我将所有库都放在 CLASSPATH 中 据我了解这个问题 https stackoverflow com questions 3376840 clojure clas
  • 如何创建 Clojure 拉链

    我如何使用 Clojure Zipper 创建以下图表 vector zip A B C D E F 我努力了 vector zip A B C D E F 它返回 A B C D E F nil 这样对吗 是的这是对的 对您的代码的一些测
  • 如何创建惰性序列向量

    运行它按预期工作 defn long seq n lazy seq cons list n somekey n 2 long seq n 1 take 3 long seq 3 gt 3 somekey 6 4 somekey 8 5 so
  • 面向 Clojure 用户的 Java

    我一直在断断续续地使用 Lisp 并且正在赶上 clojure clojure的好处是我可以自然地使用所有的java函数 而clojure的坏处也是我必须自然地了解java函数 例如 我不得不花一些时间 谷歌搜索 来查找 Java 中的平方
  • 什么时候应该在 Clojure 中使用临时重新绑定特殊变量这一习惯用法?

    我注意到一些库 例如 clojure twitter 使用特殊的变量 用于动态绑定的变量 被星号包围 进行 oauth 身份验证 您将身份验证保存在 var 中 然后使用 with oauth myauth 我认为这是解决此类问题的一个非常
  • 用于正则表达式匹配及其在字符串中的位置的紧凑 Clojure 代码

    斯图尔特 哈洛威举了个例子 re seq w The quick brown fox 作为在 Clojure 中查找正则表达式匹配项的自然方法 在他的书中 这种构造与匹配器上的迭代进行了对比 如果人们关心的只是一份比赛列表 那就太好了 但是
  • 这两个 clojure 函数之间有什么区别和问题?

    对于课程项目的一部分 我正在实现一个函数来从文件中读取一些数据并根据该文件创建图形结构 一整天我问了几个问题 结果就是这样 下面是一个可以正常工作的函数 它首先以惰性序列的形式读入文件 然后循环解析每一行并将其打印出来 defn print
  • Clojure 宏:从地图创建本地变量 [重复]

    这个问题在这里已经有答案了 我有这个示例代码 我通过迭代映射的键值对来创建变量 defmacro block bindings body let mapcat fn k v if symbol k k symbol name k v bin
  • 为什么我的 Camel Netty 路由会在 JMS 消息的开头添加换行符?

    我有一个 Camel Netty 路由 它将 XML 发送到服务器端口并将其放入 JMS 消息中 在第一条消息之后 所有其他消息的顶部都有一个换行符 导致当 GUI 收到它时 我的 XML 无法解组 我的路线是这样的
  • Clojure:生成所有键盘可输入字符

    Context 我想生成可以通过以下方式生成的所有字符 打开记事本 按键盘上的单个键 按住 Shift 按键盘上的单个键 我目前拥有的 concat range int a int z range int A int Z range int
  • 将向量作为绑定传递给 for 宏时出现问题

    我有任意数量的列表 我想使用 for 宏来处理它们 我想创建一个传递向量作为绑定的函数 因为列表的数量各不相同 如果我对绑定进行硬编码 它会按我的预期工作 gt def list1 pink green gt def list2 dog c
  • Scala - Java = ? (或者 Clojure - Java = ?)

    开发人员可以在不懂 Java 的情况下使用 Scala 吗 开发人员可以在不懂 Java 的情况下使用 Clojure 吗 注意 例如 我是一名 C 开发人员 我在不了解任何 VB 的情况下使用 NET 当然 WF 4 0 使用 VB 进行
  • Leiningen 在构建可用的 uberjar 时遇到问题

    我们正在尝试与 Leiningen 一起构建我们的 Clojure 项目 我们通过执行以下操作成功创建了 uberjar 前提条件 project clj 文件列出了依赖项 main my project core在项目 clj中 core
  • clojure 要求语法原理

    我很难理解 因此记住 此处描述的 clojure require 语法 http clojuredocs org clojure core 1 3 0 clojure core require http clojuredocs org cl
  • Clojure 宏expand

    Why does macroexpand arm getHand getFinger 扩展到 arm getHand getFinger while macroexpand gt arm getHand getFinger 扩展到 getF

随机推荐