0

HTTPリクエストを介してユーザーのアバターを作成/更新および取得することを主な目的として、OpenFireXMPPサーバー用のVCardプラグインを開発しました。残念ながら、プラグインは期待どおりに機能しません。VCardの変更はデータベース(ofVcardテーブル)に伝達されますが、userpicが更新されたユーザーもその仲間も更新された画像を見ることができません。VCardを作成/更新する方法は次のとおりです。

   ...
   XMPPServer server = XMPPServer.getInstance();
   VCardManager vcardManager = server.getVCardManager();

public void createOrUpdateVcard(String username, String vcard)
                              throws Exception {
                    SAXReader reader = new SAXReader();
                    reader.setValidation(false);
                    // convert String into InputStream
                    InputStream is = new ByteArrayInputStream(vcard.getBytes());
                    // read it with BufferedReader
                    BufferedReader br = new BufferedReader(new InputStreamReader(is));

                    try {
                              // Reading malformed XML will lead to DocumentException
                              Document document = reader.read(is);
                              Element vCardElement = document.getRootElement();
                              log.info("Username: " + username);
                              vcardManager.setVCard(username, vCardElement);
                    } catch (DocumentException e) {
                              throw new MalformedXmlException(e);
                    }
     }
     ...

クライアントから直接アバターを変更すると(Jitsiを使用しています)、変更はすぐにデータベースに保存されるだけでなく、すべてのバディが更新された画像を取得します。私VCardManagerが使用しているは、イベントを内部的にディスパッチしていることがわかります。

VCardEventDispatcher.dispatchVCardUpdated(username, newvCard);

しかし、それらは何の効果もないようです。

メソッドがinsetVcardから呼び出される方法と自分のコードで呼び出される方法の違いが何であるかを理解できません。私は何が欠けていますか?handleIQ(IQ packet)IQvCardHandler

4

1 に答える 1

4

わかりました、私は自分の質問に自分で答えます-多分誰かがこの情報が役に立つと思うでしょう。

画像をデータベースに保存するほど単純ではないことが判明しました。関係者間で行われることが予想されるメッセージ交換があります。この交換の重要な部分は、クライアントから送信されるプレゼンスの更新があり、サーバーとその結果としてすべての仲間に新しいプロファイルイメージについて通知することです。詳細については、XEP-0153:vCardベースのアバターを参照してください。これは、ユーザーのすべてのバディに送信されるプレゼンス更新を「エミュレート」するコードの一部です。

    public void createOrUpdateVcard(String username, String vcard)
        throws MalformedXmlException, UserNotFoundException, SetVcardException {
    SAXReader reader = new SAXReader();
    reader.setValidation(false);
    InputStream is = new ByteArrayInputStream(vcard.getBytes());

    try {
        // Reading malformed XML will lead to DocumentException
        Document document = reader.read(is);
        Element vCardElement = document.getRootElement();
        //Checking that the user exists
        User user = userManager.getUser(username);
        //This might be redundant
        String userUsername = user.getUsername();
        log.debug("Setting VCard for " + userUsername);
        //Storing vCard into the database
        VCardManager.getInstance().setVCard(userUsername, vCardElement);        


        Presence presence = new Presence();
        JID userJID = server.createJID(username, null);
        presence.setFrom(userJID);
        presence.setStatus("");
        presence.setPriority(30);

        Element xElement = presence.addChildElement("x", "vcard-temp:x:update");
        Element photoElement = xElement.addElement("photo");

        SecureRandom random = new SecureRandom();
                    //We do not care about the actual hash - just push updates every time
        String fakeHash = new BigInteger(130, random).toString(32);
        photoElement.setText(fakeHash);

        Element cElement = presence.addChildElement("c", "http://jabber.org/protocol/caps");
        cElement.addAttribute( "ext", "voice-v1 video-v1 camera-v1" )
        .addAttribute("hash", "sha-1");

        System.out.println("SENDING PRESENCE UPDATE:\n" + presence.toXML());
        broadcastUpdate(presence);

    } catch (DocumentException e) {
        throw new MalformedXmlException(e);
    }catch (UserNotFoundException e){
        throw new UserNotFoundException();
    } catch (Exception e){
        //Unfortunately setVCard method above just throws Exception.
        //This catch block is for wrapping it up
        throw new SetVcardException();
    }
}

これは、PresenceUpdateHandlerクラスから少し調整されたメソッドです。

private void broadcastUpdate(Presence update) {
    if (update.getFrom() == null) {
        return;
    }
    if (localServer.isLocal(update.getFrom())) {
        // Do nothing if roster service is disabled
        if (!RosterManager.isRosterServiceEnabled()) {
            return;
        }
        // Local updates can simply run through the roster of the local user
        String name = update.getFrom().getNode();
        try {
            if (name != null && !"".equals(name)) {
                Roster roster = rosterManager.getRoster(name);
                roster.broadcastPresence(update);
            }
        }
        catch (UserNotFoundException e) {
            log.warn("Presence being sent from unknown user " + name, e);
        }
        catch (PacketException e) {
            log.error(LocaleUtils.getLocalizedString("admin.error"), e);
        }
    }
    else {
        // Foreign updates will do a reverse lookup of entries in rosters
        // on the server
        log.warn("Presence requested from server "
                + localServer.getServerInfo().getXMPPDomain()
                + " by unknown user: " + update.getFrom());
    }
}

OpenFireの問題をデバッグするには、ローカルでデバッグモードで実行することを強くお勧めします。手順は次のとおりです。2。新しいEclipseリリースには既存のソースからプロジェクトを作成する機能がないことに注意してください。ただし、[新規]-> [Javaプロジェクト]をクリックし、[デフォルトの場所を使用する]チェックボックスをオフにして、プロジェクトの場所を参照する必要があります。

于 2012-07-06T14:05:56.173 に答える