2012-09-03 35 views
4

我正在嘗試爲Android(使用Java連接到C#/ Unity)開發XMPP聊天客戶端。我已經得到了Java - > Unity/C#連接的完美工作。我也下載了Asmack,並可以生成一個庫和我的封裝類來初始化與OpenFire XMPP服務器的連接。但是,我似乎無法獲得Presence的發送或接收。我可以登錄,註冊新用戶並填寫他們的名單,發送消息,但不能發送任何消息。無法通過ASmack發送或接收狀態

代碼自動註冊從未使用過此應用程序的用戶。它還使用預設的好友列表,並自動使用這些朋友填充名單。通過設置存在監聽和通過獲取

public class ASmackWrapper 
{ 
    private XMPPConnection connection; 
    private String[] friends; 
    private static final String eventClass = "ASmackEventListener"; 
    private static ASmackWrapper wrapper; 

    public static ASmackWrapper instance() 
    { 
     System.out.println("instancecreator of ASmackWrapper 1!"); 
     if (wrapper == null) 
      wrapper = new ASmackWrapper(); 
     return wrapper; 
    } 

    public ASmackWrapper() 
    { 
     System.out.println("constructor of ASmackWrapper"); 
    } 

    public boolean tryToRegister(String user, String pass){ 
     AccountManager acManager = connection.getAccountManager(); 
     try { 
      Map<String, String> attributes = new HashMap<String,String>(); 
      attributes.put("email", "MY email"); 
      acManager.createAccount(user, pass,attributes); 
     } catch (XMPPException e) { 
      System.out.println("cant autoregister user "+ user +" ... with pass: "+pass+" on server. error:" + e.getLocalizedMessage()); 
      if (e.getLocalizedMessage().contains("conflict")) 
       return false; // Wrong password, since there is already an account with that id! 
      return false; 
     } 
     return true; 
    } 

    public void setFriends(String[] _friends) { 
     friends = _friends; 
    } 

    public void start(String host, String user, String pass) 
    { 
     System.out.println("Java: openConenction host:"+host); 
     ConnectionConfiguration cc = new ConnectionConfiguration(host,5222); 
     //cc.setSendPresence(true); 
     this.connection = new XMPPConnection(cc); 
     Connection.DEBUG_ENABLED = true; 
     try { 
      this.connection.connect(); 
     } catch (XMPPException e) { 
      System.out.println("Error connecting to server"); 
      return; 
     } 

     if(!this.connection.isConnected()) { 
      System.out.println("Java: is not connected"); 
      onError("Connection failed"); 
      return; 
     } 

     boolean loginStatus = login(user, pass); 
     if (!loginStatus) { 
      onError("Login Failed"); 
      return; 
     } 

     RosterListener rl = new RosterListener() { 
      public void entriesAdded(Collection<String> addresses) {} 
      public void entriesUpdated(Collection<String> addresses) {} 
      public void entriesDeleted(Collection<String> addresses) {} 
      public void presenceChanged(Presence presence) { 
       System.out.println("presence changed!" + presence.getFrom() + " "+presence.getStatus()); 
       onPresence(presence); 
      } 
     }; 
     if (connection.getRoster() != null) { 
      connection.getRoster().setSubscriptionMode(Roster.SubscriptionMode.accept_all); 

      System.out.println("7"); 
      connection.getRoster().addRosterListener(rl); 
     } 

     onAuthenticate(""); 
     System.out.println("10"); 

     //Set presence to online! 
     Presence presence = new Presence(Presence.Type.available); 
     presence.setStatus("Online, Programmatically!"); 
     presence.setPriority(24); 
     presence.setMode(Presence.Mode.available); 
     connection.sendPacket(presence); 
    } 

    private void addFriends() throws Exception { 
     if (friends == null) { 
      System.out.println("No friends to add"); 
      return; 
     } 
     System.out.println("Number of friends to add: "+friends.length); 
     for (int i = 0;i<friends.length;i++) { 
      System.out.println("Create user in roster: "+friends[i]); 
      connection.getRoster().createEntry("fb"+friends[i], "No name_",null); 
     } 
    } 

    private boolean login(String jid, String password) { 
     System.out.println("1"); 
     boolean isLoggedIn=true; 
     try { 
      this.connection.login(jid, password); 
     } catch (XMPPException e) { 
      isLoggedIn=false; 
     } 

     System.out.println("2"); 
     if(!isLoggedIn) { 
      boolean isRegistred = tryToRegister(jid,password); 
      if (isRegistred) { 
       connection.disconnect(); 
       try { 
        connection.connect(); 
        connection.login(jid, password); 
       } catch (XMPPException e) { 
        onError("Could not connect and login after registring"); 
        return false; 
       } 
      } else { 
       return false; 
      } 
     } 

     try { 
      addFriends(); 
     } catch (Exception e) { 
      onError("Could not add friends to roster"); 
     } 
     ChatManager chatmanager = connection.getChatManager(); 

     chatmanager.addChatListener(new ChatManagerListener() 
     { 
      public void chatCreated(final Chat chat, final boolean createdLocally) 
      { 
       System.out.println("OK Chat created!"); 
       chat.addMessageListener(new MessageListener() 
       { 
        public void processMessage(Chat chat, Message message) 
        { 
         onMessage(chat, message); 
        } 
       }); 
      } 
     }); 

     return true; 
    } 

    public void sendMessage(String rec, String message) { 
     System.out.println("sendMessage(string,string) to host :"+connection.getHost()); 
     Chat chat = connection.getChatManager().createChat(rec+"@"+connection.getHost(), new MessageListener() { 
      public void processMessage(Chat chat, Message message) { 
       // Print out any messages we get back to standard out. 
       System.out.println("Probably an error, since we got a instant reply on sent message. Received message body: " + message.getBody() + " from:"+message.getFrom() + " to:"+message.getTo()); 
      } 
     }); 
     try { 
      chat.sendMessage(message); 
      System.out.println("Message sent"); 
     } catch (XMPPException e) { 
      System.out.println("Error sending message: "+e.toString()); 
      e.printStackTrace(); 

     } 
    } 

    public void logout() { 
     System.out.println("Login out..."); 
     connection.disconnect(); 
    } 

    public void getOnlineFriends() { 
     Roster roster = connection.getRoster(); 
     Collection<RosterEntry> entries = roster.getEntries(); 

     for(RosterEntry rosterEntry: entries) { 
      String user = rosterEntry.getUser(); 
      Presence presence = roster.getPresence(user); 
      System.out.println("Presence : "+presence);          
      System.out.println("Presence type: "+presence.getType());     
      System.out.println("Presence mode: "+presence.getMode()); 
     } 

     //Set presence to online! 
     Presence presence = new Presence(Presence.Type.available); 
     presence.setStatus("Online, Programmatically!"); 
     presence.setPriority(24); 
     presence.setMode(Presence.Mode.available); 
     connection.sendPacket(presence); 
    } 

    private void onMessage(Chat chat, Message message) { 
     String m = ("Received message: " + (message != null ? message.getBody() : "NULL")); 
     System.out.println(m); 

     UnityPlayer.UnitySendMessage(eventClass, "Message", m); 
    } 

    private void onError(String message) { 
     UnityPlayer.UnitySendMessage(eventClass, "Error", message); 
    } 

    private void onAuthenticate(String message) { 
     UnityPlayer.UnitySendMessage(eventClass, "Authenticate", message); 
    } 

    private void onPresence(Presence presence) { 
     String user = presence.getFrom(); 
     if (presence.getType() == Presence.Type.available) 
      UnityPlayer.UnitySendMessage(eventClass, "Online", user); 
     else 
      UnityPlayer.UnitySendMessage(eventClass, "Offline", user); 

      System.out.println("Java: Presence changed, from:" +presence.getFrom() + " type:"+presence.getType() + " toString:"+presence.toString()); 
    } 


} 

存在以兩種方式檢查:

的代碼是如下(抱歉所有調試線,不能使用Unity時使用斷點)登錄後的狀態。這個SO頁面建議等5秒後才能獲得版本號:Unable to get presence of roster by using smack, openfire 我已經嘗試過,並且通過從一個按鈕中調用getOnlineFriends,並在登錄後超過5秒鐘。聽衆永遠不會被叫到。它只是登錄後觸發一次,每次在陣容中都有一個存在= null。

編輯:上Asmack開機調試模式後,我看到了如下答覆我的存在發送消息:

SENT <presence id="3sG7l-11"><status>Online, Programmatically!</status><priority>24</priority></presence> 

RCV <presence id="6s7BX-5" to="[email protected]/Smack" from="10000063946242" type="error"> 
<error code="404" type="cancel"> 
<remote-server-not-found xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/> 
</error></presence> 

服務器日誌:

org.jivesoftware.openfire.nio.ConnectionHandler - Closing connection due to error while processing message: 
<iq id="566-4" type="error" from="xxx.tripnet.se/f55aea72" to="xxx.tripnet.se"> 
<error /><error type="cancel" code="501"> 
<feature-not-implemented xmlns="urn:ietf:params:xml:ns:xmpp-stanzas" /></error> 
<ping xmlns="urn:xmpp:ping" /></iq> 

java.lang.IllegalArgumentException: IQ must be of type 'set' or 'get'. Original IQ: 
<iq id="566-4" type="error" from="xxx.tripnet.se/f55aea72" to="xxx.tripnet.se"> 
<error/><error type="cancel" code="501"> 
<feature-not-implemented xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></error> 
<ping xmlns="urn:xmpp:ping"/></iq> 
at org.xmpp.packet.IQ.createResultIQ(IQ.java:384) 

我也試圖通過沿setSendPresence = true傳遞給Connect()中傳遞的連接配置,但沒有區別。

我也嘗試在OpenFire服務器上手動設置訂閱模式爲「both」(來自「none」)兩個用戶,但沒有任何效果。

+0

也許是最新版本中的錯誤? :S http://community.igniterealtime.org/thread/43986 – Sunkas

+0

我最近的線索是名單上的jid格式錯誤。但從「id」更改爲「[email protected]」沒有幫助:( – Sunkas

回答

3

讓它工作!這可能是因爲我沒有在名單中的我的jid上使用正確的格式。正確的格式必須是[email protected],而不僅僅是用戶

1

寫一個RosterListener,看它是否有效。

public void rosterOnlineStatus(){ 
    Roster roster = connection.getRoster(); 
    Presence status = new Presence(Type.available); 
    status.setStatus("Hello This is Phaneendra"); 
    roster.addRosterListener(new RosterListener() { 

     @Override 
     public void presenceChanged(Presence presence) { 

      System.out.println(presence.getFrom()+ "is "+presence+" "+presence.getStatus()); 
      presence.getStatus(); 


     } 

     @Override 
     public void entriesUpdated(Collection<String> addresses) {} 

     @Override 
     public void entriesDeleted(Collection<String> addresses) {} 

     @Override 
     public void entriesAdded(Collection<String> addresses) {} 
    }); 
} 

看看是否添加RosterListener將工作?

+0

我已經解決了它,請參閱已批准的答案。 – Sunkas