本文介绍了Java Interop - Netty + Clojure的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想通过clojure使用netty。我可以启动服务器,但是,它无法初始化一个接受的套接字。以下是错误消息和代码。有人知道什么是/或可能是错误?我相信问题是(Channels / pipeline(server-handler))谢谢。



 #< NioServerSocketChannel [id:0x01c888d9,/0.0.0.0:843] 
2012年6月6日12:15:35 org.jboss.netty.channel.socket.nio.NioServerSocketPipelineSink
警告:无法初始化接受的套接字。
java.lang.IllegalArgumentException:找不到匹配的方法:pipeline

clj

 (defproject协议1.0.0-SNAPSHOT
:description上传协议服务器
:dependencies [
[org.clojure / clojure1.2.1]
[io.netty / netty3.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>)


netty handler。
[]
(proxy [SimpleChannelHandler] []
(messageReceived [ctx e]
(let [ch(.getChannel e)]
.write ch policy)
(.close ch)))

(channelConnected [ctx e]
(let [ch(.getChannel e)]
写ch的策略)
(.close ch)))

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

(defn setup-pipeline
返回渠道流水线。
[]
(proxy [ChannelPipelineFactory]
(getPipeline []
(Channels / pipeline(server-handler))))

(defn startup
启动netty服务器。
[port]
(let [channel-factory(NioServerSocketChannelFactory。(Executors / newCachedThreadPool)(Executors / newCachedThreadPool))
bootstrap(ServerBootstrap。channel-factory)]
(.setPipelineFactory bootstrap ()。)
(.setOption bootstrapchild.tcpNoDelaytrue)
(.setOption bootstrapchild.keepAlivetrue)
(.bind bootstrap(InetSocketAddress。


解决方案

您的代码有三个问题


  1. 使用vararg Channels.channel()方法的Java互操作。
    你可以创建一个通道处理程序的向量并用(into-array ChannelHandler ..)


  2. 您不能将String对象直接写入Netty通道。
    你必须先将字符串写入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
返回netty处理程序。
[]
(proxy [SimpleChannelHandler] []
(messageReceived [ctx e]
(let [ch(.getChannel e)]
(.addListener
(.write ch policy)
(ChannelFutureListener / CLOSE))))

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

(exceptionCaught [ctx e]
(let [ex(.getCause e)]
(printlnExceptionex)
( - e .getChannel .close)))))

(defn setup-pipeline
返回通道管道。
[]
(proxy [ChannelPipelineFactory]
(getPipeline []
(let [handler(server-handler)]
(Channels / pipeline(into-array ChannelHandler [handler])))))



(defn startup
启动netty服务器。
[port]
(let [channel-factory(NioServerSocketChannelFactory(Executors / newCachedThreadPool) / newCachedThreadPool))
bootstrap(ServerBootstrap。channel-factory)]
(.setPipelineFactory bootstrap(setup-pipeline))
(.setOption bootstrapchild.tcpNoDelaytrue)
(.setOption bootstrapchild.keepAlivetrue)
(.bind bootstrap(InetSocketAddress。port))))


b $ b

查看(也使用Netty),可用于在许多不同协议中构建客户端和服务器with nice Clojure API。


I'm trying to use netty via clojure. I'm able to startup the server, however, it fails to initialize an accepted socket. Below are the error message and code respectively. Does anyone know what is/or could be wrong? I believe the issue is with (Channels/pipeline (server-handler)) Thanks.

Error Message

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

project.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))))
解决方案

There are three problems with your code

  1. Java interop with vararg Channels.channel() method.you can make a vector of channel handlers and wrap it with (into-array ChannelHandler ..)

  2. You can not write String objects directly to a Netty Channel.you have to write the string to a ChannelBuffer first and write that buffer or use a StringCodecHandler.

  3. Writing to Netty channel is asynchronus, so you can not close it immediately.you have to register a future listener and close the channel when its done.

Here is the working code.

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

Have a look at Aleph (also uses Netty) which can used to build clients and servers in many different protocols with nice Clojure API.

这篇关于Java Interop - Netty + Clojure的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-14 15:58