cha*_*lle 5 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))))))
Run Code Online (Sandbox Code Playgroud)
写函数是基本的:
(defn write-message [msg]
(doto (:out @conn)
(.println (str msg "\r"))
(.flush)))
Run Code Online (Sandbox Code Playgroud)
这工作一次,但大部分时间我尝试它(从浏览器,它使用Javascript ping API,然后调用Java应用程序)我得到:
Connection reset stack trace:
{:class java.net.SocketException,
:message "Connection reset",
:trace-elems ({:method "read",
:class "java.net.SocketInputStream",
Run Code Online (Sandbox Code Playgroud)
当我这样做时,我打开了几个终端窗口.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"
Run Code Online (Sandbox Code Playgroud)
我意识到像"POST"和"内容类型"这样的东西在这种情况下毫无意义,因为我们不是在谈论HTTP服务器.不过,他们似乎没有任何伤害.此curl请求返回正确的响应.
但Clojure应用程序只会出错.
我可以相信这2个应用程序与端口8080有冲突,但我不明白这个冲突的性质.
有什么建议?
在将来,我们认为我们将放弃Socket,而是使用Redis或作业队列进行通信,但是现在我们正在使用Socket,我想让它正常工作.
现在我只需要Clojure应用程序就像curl一样工作.
| 归档时间: |
|
| 查看次数: |
689 次 |
| 最近记录: |