什么是最简单的Clojure套接字调用,类似于“curl”? (处理java.net.SocketException)

时间:2015-07-06 16:07:43

标签: java sockets curl clojure

我们的服务器上有2个应用程序。一个是Java应用程序,用普通英语编写的句子中提取重要的信息块。它应该只与我们服务器上的其他应用程序通信(尽管我们还没有设置防火墙来保护它)。它不应该与公众交谈(尽管目前是可能的)。它有一些非常简单的Java代码,它在端口8080上打开一个Socket然后监听。它希望收到一个可以转换为JSON的字符串。它发回一个可以转换为JSON的字符串。它不会发回任何HTTP头,它只是你能想象到的最简单的Socket代码,甚至不是30行代码。

我们有另一个用Clojure编写的应用程序,它通过RESTful API与广阔的世界交流。

基本思想是请求从外部世界进入我们的服务器,并与Clojure应用程序进行交互。 Clojure应用程序假设与Java应用程序交互,然后Clojure应用程序向任何查询它的人发回响应。

我无法弄清楚如何从Clojure应用程序中调用Java应用程序。我试图使用像clj-http这样的库,但它依赖于Apache HttpClient,它假设响应将包含正确的HTTP头。 Apache HttpClient在与Java应用程序交互时抛出了异常,因为Java应用程序只发回一个字符串(没有HTTP头)。我不想在Java应用程序中编写完整的HTTP代码,因为这与我们在Clojure应用程序中所做的工作相关。

所以,我改变了战术,并从Clojure方面编写了一些原始的Socket代码。该代码如下:

(def conn (ref {:in nil :out nil}))

(defn connect []
  (let [socket (Socket. "localhost" 8080)
    in (BufferedReader. (InputStreamReader. (.getInputStream socket)))
    out (PrintWriter. (.getOutputStream socket))]
  (dosync
   (alter conn
        (fn [old-value] (assoc old-value :in in)))
   (alter conn
        (fn [old-value] (assoc old-value :out out))))))

写函数是基本的:

(defn write-message [msg]
  (doto (:out @conn)
    (.println (str msg "\r"))
    (.flush)))

这个工作过一次,但大部分时间我都尝试过(从浏览器,它使用Javascript来ping API,然后调用Java应用程序)我得到:

Connection reset stack trace: 
    {:class java.net.SocketException, 
     :message "Connection reset", 
     :trace-elems ({:method "read",          
     :class "java.net.SocketInputStream", 

当我这样做时,我打开了几个终端窗口。 Java应用程序的终端根本没有显示任何活动,而Clojure应用程序显示上述错误。

如果我使用这个curl(直接点击Java应用程序),那么一切正常:

curl --verbose "http://localhost:8080" -d '  { "transaction-id" : "99393920", "report" : "Allie Hanther of IBM responded to our proposal and said her company is ready to move forward. The deal is worth $400,000 annually. I will meet with her tomorrow and we will sign the contract." } '   -X POST   --header "Content-Type:application/json"

我意识到像“POST”和“content type”这样的东西在这种情况下毫无意义,因为我们不是在谈论HTTP服务器。不过,他们似乎没有任何伤害。此curl请求返回正确的响应。

但是Clojure应用程序只会出错。

我可以相信这2个应用程序与端口8080存在冲突,但我不明白该冲突的性质。

有什么建议吗?

将来,我们认为我们将放弃Socket,而是使用Redis或作业队列进行通信,但是现在我们正在使用Socket,我想让它正常工作。

现在我只需要Clojure应用程序像curl一样工作。

0 个答案:

没有答案