4

Android用のXMPPチャットクライアントを開発しようとしています(C#/ Unityに接続されたJavaを使用)。Java-> Unity / C#接続が完全に機能しています。Asmackもダウンロードし、OpenFireXMPPサーバーへの接続を開始するためのライブラリとラッパークラスを生成できます。ただし、プレゼンスを送受信できないようです。ログインして新しいユーザーを登録し、その名簿にデータを入力してメッセージを送信することはできますが、プレゼンスを送信することはできません。

このコードは、これまでアプリを使用したことがないユーザーを自動登録します。また、事前設定された友達リストを使用し、これらの友達を名簿に自動的に入力します。

コードは次のとおりです(すべてのデバッグ行で申し訳ありませんが、Unityを使用している場合はブレークポイントを使用できません):

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


}

プレゼンスは、プレゼンスリスナーを設定する方法と、ログイン後にステータスを取得する方法の2つの方法でチェックされます。このSOページは、プレセンスを取得する前に5秒待つことを提案しています。smack 、openfireを使用して名簿の存在を取得できません 。ログイン後5秒以上、ボタンからgetOnlineFriendsを呼び出して、これも試しました。リスナーが呼び出されることはありません。ログイン後に1回だけ起動し、presence=nullの名簿に1回ずつ起動します。

編集: Asmackでデバッグモードをオンにした後、プレゼンス送信メッセージに対する次の応答が表示されます。

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

RCV <presence id="6s7BX-5" to="787122012@xxx.tripnet.se/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) 

また、connect()で渡されたconnectionconfigurationにsetSendPresence = trueを渡そうとしましたが、違いはありません。

また、OpenFireサーバーでサブスクリプションモードを手動で両方のユーザーの「両方」(「なし」から)に設定しようとしましたが、効果がありません。

4

2 に答える 2

3

動作しました!おそらく、名簿リストのjidで正しい形式を使用しなかったことが原因でした。正しい形式は、 userだけでなく、user @myserver.seである必要がありました。

于 2012-09-03T15:35:55.180 に答える
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の追加が機能するかどうかを確認しますか?

于 2013-11-19T13:43:24.783 に答える