1

现在正在使用 Android 中的 Xmpp 文件传输。在发送文件时,它会给出 503 服务不可用错误。

>    07-29 15:33:12.183: D/SMACK(22151): 03:33:12 PM SENT (1095973320):
> <iq id="s9DTB-10" to="jithu4@jabber.org/Smack"
> from="jithu1@jabber.org/Smack" type="set"><si
> xmlns="http://jabber.org/protocol/si" id="jsi_6388535575928662640"
> mime-type="image/jpeg"
> profile="http://jabber.org/protocol/si/profile/file-transfer"><file
> xmlns="http://jabber.org/protocol/si/profile/file-transfer"
> name="IMG_20130715_115622_1445552069.jpg" size="2105955"
> ><desc>test_file</desc></file><feature xmlns="http://jabber.org/protocol/feature-neg"><x
> xmlns="jabber:x:data" type="form"><field var="stream-method"
> type="list-single"><option><value>http://jabber.org/protocol/bytestreams</value></option><option><value>http://jabber.org/protocol/ibb</value></option></field></x></feature></si></iq>

之后它会给出这样的响应

> 07-29 15:33:12.708: D/SMACK(22151): 03:33:12 PM RCV  (1095973320): <iq
> from='jithu4@jabber.org/Smack' to='jithu1@jabber.org/Smack'
> type='error' id='s9DTB-10'><error code='503'
> type='cancel'><service-unavailable
> xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/></error></iq>

我正在使用asmack-android-6-0.8.1.1.jar

请帮助我,为什么会发生这个 503 错误。

4

2 回答 2

0

将服务发现添加到您的代码中。您可以使用以下代码进行文件传输。

ServiceDiscoveryManager sdm = ServiceDiscoveryManager
            .getInstanceFor(kXmppConnection);
    if (sdm == null)
        sdm = new ServiceDiscoveryManager(XmppConnection);
    sdm.addFeature("http://jabber.org/protocol/disco#info");
    sdm.addFeature("jabber:iq:privacy");
    FileTransferNegotiator.setServiceEnabled(kXmppConnection,
            true);
    FileTransferManager manager = new FileTransferManager(
            kXmppConnection);

    final OutgoingFileTransfer transfer = manager
            .createOutgoingFileTransfer(jid + "/Smack");
    File file = new File(file_path);
    try {
        transfer.sendFile(file, "test_file");
    } catch (XMPPException e) {
        e.printStackTrace();

    }
    new AsyncTask<Void, Void, Void>() {


        protected void onPreExecute() {

        }

        @Override
        protected Void doInBackground(Void... params) {
            while (!transfer.isDone()) {
                if (transfer.getStatus().equals("Error")) {
                    Log.d("file transfer",
                            "ERROR!!! " + transfer.getError());

                } else if (transfer.getStatus().equals("Cancelled")
                        || transfer.getStatus().equals("Refused")) {
                    Log.d("file transfer",
                            "Cancelled!!! " + transfer.getError());
                }
                try {
                    Thread.sleep(1000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return null;
        };

        protected void onPostExecute(Void result) {

            if (transfer.getStatus().equals("Refused")
                    || transfer.getStatus().equals("Error")
                    || transfer.getStatus().equals("Cancelled")) {
                Log.i("file transfer", "refused cancelled error "
                        + transfer.getError());

            } else {

                Log.i("file transfer", "Success: " + transfer.getFileName());
            }
        };
    }.execute();
于 2014-11-06T05:52:26.673 回答
0

我有同样的问题,我调查了这节并以这种方式解决了它。

许多人使用“/Smack ”或“/Resource”作为jid 中的资源部分,但这可以通过另一种方式完成。

资源路径随着用户的每次改变而改变。假设我们想向这个用户发送图像: “user1@mydomain”

您必须在此 jid 中添加“/Resource”或“/Smack”部分,它变为: user1@mydomain/Resource

但是资源路径会随着存在而改变,因此您必须遵循每个存在更改来更新资源路径。最好的方法是让用户存在是在名册侦听器中,在 presencheChanged() 方法中,您可以获得最后一个用户资源部分,如下所示:

Roster roster=getRoster();
roster.addRosterListener(new RosterListener() {
                @Override
                public void entriesAdded(Collection<Jid> addresses) {
                    Log.d("entriesAdded", "ug");
                    context.sendBroadcast(new Intent("ENTRIES_ADDED"));
                }

                @Override
                public void entriesUpdated(Collection<Jid> addresses) {
                    Log.d("entriesUpdated", "ug");
                }

                @Override
                public void entriesDeleted(Collection<Jid> addresses) {
                    Log.d("entriesDeleted", "ug");
                }

                @Override
                public void presenceChanged(Presence presence) {
                    Log.d("presenceChanged", "ug");
                    //Resource from presence
                    String resource = presence.getFrom().getResourceOrEmpty().toString();
                    //Update resource part for user in DB or preferences
                    //...
                }
            });
}

资源字符串将是一些生成的字符串,如“6u1613j3kv ”,jid 将变为: user1@mydomain/6u1613j3kv

这意味着您必须像这样创建传出传输:

EntityFullJid jid = JidCreate.entityFullFrom("user1@mydomain/6u1613j3kv"); 
OutgoingFileTransfer transfer = manager.createOutgoingFileTransfer(jid)

这就是我在 smack 和 Openfire 上解决文件传输问题的方法。

还要提一下,您必须在 Openfire 服务器中添加以下属性:

xmpp.proxy.enabled - true
xmpp.proxy.externalip - MY_IP_ADDRESS
xmpp.proxy.port -7777

顺便提一下,我使用的是 Openfire 4.0.2 和 Smack 4.2.2。

这也可以通过简单的方式进行配置,只需将资源设置为

XMPPTCPConnectionConfiguration.Builder 。

喜欢

XMPPTCPConnectionConfiguration.Builder configurationBuilder = 
XMPPTCPConnectionConfiguration.builder(); 

configurationBuilder.setResource("yourResourceName");
于 2018-02-15T21:39:56.087 回答