如何使用SMACK库在客户端处理XMPP XEP-0363:HTTP文件上传功能?

3

SMACK是否有用于处理“XEP-0363: HTTP文件上传”功能的客户端接口?如果没有,那么是否有其他标准的客户端接口可供使用?

我可以使用自定义IQ来完成它。

    IQ iq = new IQ("request", "urn:xmpp:http:upload") {
        @Override
        protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) {
            xml.rightAngleBracket();
            xml.element("filename", "text.png");
            xml.element("size", "1645");
            return xml;
        }
    iq.setType(IQ.Type.get);
    iq.setFrom("testa@localhost/Smack");
    iq.setTo("upload.localhost");

And,

connection.sendStanza(iq);
1个回答

0
我使用简单的类来实现这个功能:
package mypkg;

import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.StanzaListener;
import org.jivesoftware.smack.filter.StanzaFilter;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.packet.XMPPError;
import org.jivesoftware.smack.provider.IntrospectionProvider;
import org.jivesoftware.smack.provider.ProviderManager;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;

public class XEP0363 implements StanzaListener{
    private XMPPTCPConnection connection;
    private String id;
    private SlotGrantedListener listener;

    static {
        ProviderManager.addIQProvider("slot", "urn:xmpp:http:upload", new SlotIQProvider());
    }

    public static class SlotIQProvider extends IntrospectionProvider.IQIntrospectionProvider {
        public SlotIQProvider() {
            super(SlotIQ.class);
        }
    }

    public static class SlotIQ extends IQ {
        private String put;
        private String get;

        public SlotIQ() {
            super("request", "urn:xmpp:http:upload");
        }

        public String getPut() {
            return put;
        }

        public void setPut(String put) {
            this.put = put;
        }

        public String getGet() {
            return get;
        }

        public void setGet(String get) {
            this.get = get;
        }

        @Override
        protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) {
            return null;
        }
    }

    public interface SlotGrantedListener {
        void slotGranted(String put, String get);
        void slotDenied(String error);
    }

    public XEP0363(XMPPTCPConnection connection) {
        this.connection = connection;
    }

    public void requestSlot(String to, final String fileName, final long fileSize, SlotGrantedListener listener)
            throws SmackException.NotConnectedException {
        this.listener = listener;
        final IQ iq = new IQ("request", "urn:xmpp:http:upload") {
            @Override
            protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) {
                xml.rightAngleBracket();
                xml.element("filename", fileName);
                xml.element("size", String.valueOf(fileSize));
                return xml;
            }
        };
        iq.setType(IQ.Type.get);
        iq.setFrom(connection.getUser());
        iq.setTo(to);

        id = iq.getStanzaId();

        connection.addAsyncStanzaListener(this, new StanzaFilter() {
            @Override
            public boolean accept(Stanza stanza) {
                return id != null && id.equals(stanza.getStanzaId());
            }
        });

        connection.sendStanza(iq);
    }

    @Override
    public void processPacket(Stanza packet) throws SmackException.NotConnectedException {
        connection.removeAsyncStanzaListener(this);
        if (((IQ)packet).getType() != IQ.Type.error) {
            SlotIQ slotIQ = (SlotIQ) packet;
            listener.slotGranted(slotIQ.getPut(), slotIQ.getGet());
        } else {
            XMPPError error = packet.getError();
            String errDesc = error.getDescriptiveText(null);
            String errText = errDesc != null ? String.format("%s (%s)", errDesc, error.toString()) : error.toString();
            listener.slotDenied(errText);
        }
    }

}

然后,创建一个实现了 SlotGrantedListener 接口的监听器,并调用 requestSlot() 方法:
XEP0363 fileUpload = new XEP0363(connection);
fileUpload.requestSlot("upload.myxmppdomain", "mypic.jpg", 12345, listener)

请注意,此类不是线程安全的。

能否给我提供这段代码的基本思路?我是iOS开发人员,所以请解释一下。如果你有iOS代码,请提供给我。我使用了XMPP框架,并阅读了XMPP-0363,但没有理解任何内容。 - Maulik shah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接