2014-03-28 53 views
1

我有一些简单的工作java代码,它使用SMACK xmmp库,它响应传入消息并接受多用户聊天邀请。我正试图转换这个clojure。机器人登录但不响应消息。Clojure新手 - 重写Java代码到Clojure

public class bot { 

public static void main(String[] args) { 

    System.out.println("Starting session..."); 
    try { 
     String server = "chat.hipchat.com";   
     XMPPConnection con = new XMPPConnection(server); 
     con.connect(); 
     String username = "username"; 
     String password = "password"; 
     con.login(username, password,"bot"); 
     System.out.println("Connected"); 

     ChatManager chatManager = con.getChatManager(); 
     final MyMessageListener messageListener = new MyMessageListener(); 

     ChatManagerListener chatManagerListener = new ChatManagerListener() { 
      public void chatCreated(Chat chat, boolean createdLocally) { 
       chat.addMessageListener(messageListener); 
      } 
     }; 
     chatManager.addChatListener(chatManagerListener); 


     MultiUserChat.addInvitationListener(con, new InvitationListener() { 

      public void invitationReceived(XMPPConnection con, 
        String room, String arg2, String arg3, String arg4, 
        Message arg5) { 

       MultiUserChat muc2 = new MultiUserChat(con, room); 
        try { 
        muc2.join("Bot"); 
       } catch (XMPPException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     }); 
     // Thread.currentThread(); 
     Thread.sleep(10000); 
     // Disconnect from the server 
     con.disconnect(); 
    } catch (XMPPException e) { 
     e.printStackTrace(); 
    } 
    catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
    System.out.println("Ended session..."); 
} 
} 

public class MyMessageListener implements MessageListener { 

public void processMessage(Chat chat, Message message) { 
    System.out.println("Received message: " + message.getBody()); 
    try { 
     chat.sendMessage("Smack> Message sent via API."); 
    } catch (XMPPException e) { 
     e.printStackTrace(); 
    } 
} 

} 


(ns mybot.core 
(:import [org.jivesoftware.smack 
     Chat ChatManager MessageListener ChatManagerListener XMPPConnection XMPPException] 
     [org.jivesoftware.smack.packet 
     Message Presence] 
     [org.jivesoftware.smackx.muc InvitationListener MultiUserChat])) 

(def con (XMPPConnection. "chat.hipchat.com")) 


(defrecord MyMessageListener [] 
    MessageListener 
    (processMessage [this chat message] (println "Received Message"))) 


(def myMessageListner (MyMessageListener.)) 



(defn add-chatManagerListener 
    [connection] 
    (println "Adding a chat manager lister") 
    (.addChatListener (.getChatManager connection) 
       (proxy [ChatManagerListener] [] 
        (chatCreated [chat locally] 
        (.addMessageListner chat myMessageListner) 
        ) 
       ))) 




(defn -main [& args] 
    (println "Starting bot") 
    (.connect con) 
    (.login con "username" "pwd" "bot") 
(println (.isAuthenticated con)) 
(add-chatManagerListener con)) 
+0

你是什么意思的“机器人登录,但没有回应消息”? – Chiron

+0

MultiUserChat.addInvitationListener是否执行重要的事情?我在clojure代码 – GregA100k

+0

中没有看到@G_A MultiUserChat.addInvitationListener是接受聊天室邀请的列表程序。我没有补充说,在clojure代码,因为我无法得到一对一的列表本身工作 – Phani

回答

0

如果您不需要,我强烈建议您不要使用(def ...)来维护全局状态。这总是有点back。。但也许这是某种个人品味。

Clojure中的记录被用作bean,我确信你不能用它来实现接口上的方法。定义是:(defrecord name [& fields] & opts+specs)其中fields是字段名称列表,而不是方法名称。

要实例化Java接口或Clojure协议,您应该使用reify。应该使用proxy宏来扩展抽象类或覆盖类上的函数。但MessageListenerChatManagerListener只是接口,所以从我的角度来看reify应该是第一选择。

我附加了我的源代码版本,但我无法正确测试,因此请小心处理。

(ns mybot.core 
    (:import [org.jivesoftware.smack 
     Chat ChatManager MessageListener ChatManagerListener XMPPConnection XMPPException] 
     [org.jivesoftware.smack.packet 
     Message Presence] 
     [org.jivesoftware.smackx.muc InvitationListener MultiUserChat])) 

(defn connect [host username password] 
    (doto (XMPPConnection. "chat.hipchat.com") 
    (.login username password "bot"))) 

(defn add-listener [connection callback] 
    (let [chat-manager (.getChatManager connection) 
     message-listener (reify 
      MessageListener 
      (processMessage [_ chat message] (callback chat message)) 
      ) 
     chat-listener (reify 
      ChatManagerListener 
      (chatCreated [_ chat _] 
       (.addMessageListner chat message-listener))) 
    ] 
     (.addChatListener chat-manager chat-listener)  
     connection 
    )) 

(def -main [& args] 
    (let [con (connect "chat.hipchat.com" "username" "pwd")] 
    (println (.isAuthenticated con)) 
    (add-listener con (fn [_ message] (println "Received Message:" message))) 

     (Thread/sleep 10000))) 

一个常见的Clojure图案是通过回调函数为监听器,我没有为add-listener功能。这提供了很好的解耦和隐藏所有讨厌的面向对象的东西。