Android中的Xmpp FileTransnfer给503服务不可用错误

时间:2013-07-29 10:10:14

标签: android xmpp file-transfer xmppframework asmack

现在正在使用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 libs

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

2 个答案:

答案 0 :(得分: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();

答案 1 :(得分:0)

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

很多人使用&#34; / Smack &#34;或&#34; /资源&#34; 作为jid中的资源部分,但这可以通过其他方式完成。

资源路径随着用户的每次更改而变化。让我们说我们想要向这个用户发送图像: 的&#34; USER1 @ MYDOMAIN&#34;

您必须添加&#34; /资源&#34;或&#34; / Smack&#34;这个jid的一部分,它变成了这个: 的 USER1 @ MYDOMAIN /资源

但资源路径随着状态而变化,因此您必须遵循每个状态更改来更新资源路径。 最好的方法是让用户出现在名册监听器中,并在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
                    //...
                }
            });
}

资源字符串将是一些生成的字符串,如&#34; 6u1613j3kv &#34;和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");