在使用XMPP传输文件时出现错误代码503

4
我正在尝试使用smack和openfire xmpp发送图像文件。为此,我正在使用FileTransferManager类。为了使用FileTransferManager类,我使用asmack-android-6.jar。我按照这个link来共享文件。这个问题也在本教程下面的评论中共享,但是没有给出解决此问题的好方法。然后我在Stack Overflow上搜索,许多开发人员都问过这个问题,但只有1-2个人得到了回复,并且others 没有。
我学习了我找到的所有答案,尝试了谷歌给我的所有方法,但仍然无法解决这个问题。
我使用的代码是:
d.findViewById(R.id.btnsendphoto).setOnClickListener(
                    new OnClickListener() {

                        @Override
                        public void onClick(View v) {
                            // TODO Auto-generated method stub
                            if (!filepath.equals("")) {
                                ServiceDiscoveryManager sdm = ServiceDiscoveryManager
                                        .getInstanceFor(connection);

                                if (sdm == null) {
                                    sdm = new ServiceDiscoveryManager(
                                            connection);
                                    Log.e("service discovery", "SDM");
                                    sdm.addFeature("http://jabber.org/protocol/disco#info");

                                    sdm.addFeature("jabber:iq:privacy");
                                }

                                mFileTransferManager = new FileTransferManager(
                                        connection);
                                /*
                                 * OutgoingFileTransfer transfer =
                                 * mFileTransferManager
                                 * .createOutgoingFileTransfer
                                 * ("98c6d889473a6fae@pc/Smack");
                                 */
                                String to = connection.getRoster()
                                        .getPresence("98c6d889473a6fae@pc")
                                        .getFrom();
                                OutgoingFileTransfer transfer = mFileTransferManager
                                        .createOutgoingFileTransfer(to);
                                File file = new File(filepath);

                                try {
//[configureProviderManager](http://paste.ubuntu.com/9932239/)
                                    configureProviderManager(connection);
                                    transfer.sendFile(file, "test_file");
                                } catch (XMPPException e) {
                                    e.printStackTrace();
                                }
                                while(!transfer.isDone()) {
                                    Log.d("status", transfer.getStatus().toString());
                                    Log.d("percent", new Long(transfer.getBytesSent()).toString());
                                    if (transfer.getStatus() == Status.error) {
                                        Log.e("percent", "Error " + new Long(transfer.getBytesSent()).toString() + " " + transfer.getError() + " " + transfer.getException());
                                        transfer.cancel();

                                    }

                                    if(transfer.getStatus().equals(Status.refused))
                                             System.out.println("refused  " + transfer.getError());
                                    else if( transfer.getStatus().equals(Status.error))
                                         System.out.println(" error " + transfer.getError());
                                    else if(transfer.getStatus().equals(Status.cancelled))
                                       System.out.println(" cancelled  " + transfer.getError());
                                    else
                                       System.out.println("Success");



                                }

                            }
                            d.dismiss();
                        }
                    });

我得到的logcat非常大,所以我提供了它的链接。有人能告诉我我犯了什么错误,或者建议我做出什么修改来完成任务吗?


我很愿意提供帮助,但是我所能做的就是指向 https://github.com/igniterealtime/Smack/wiki/Smack-XMPP-File-Transfer。 - Flow
好的,我会学习你给的链接,感谢您的评论。 - Android Rockss
@Flow 我看了你给的链接,但是我没有在那里找到解决我的问题的方法。 - Android Rockss
链接页面的内容基本上试图告诉你,你应该能够自己解决问题。因为Smack是开源的,XMPP是一个开放的标准,所以你可以自己调试和分析失败文件传输的原因。 - Flow
我无法回复这条评论,但仍然感谢您花费宝贵的时间。 - Android Rockss
2个回答

1

这个问题通过链接的回答得到了解决,不知道为什么它被踩了。让我也在这里分享答案

d.findViewById(R.id.btnsendphoto).setOnClickListener(
                    new OnClickListener() {

                        @Override
                        public void onClick(View v) {
                            // TODO Auto-generated method stub
                            if (!filepath.equals("")) {
                                ServiceDiscoveryManager sdm = ServiceDiscoveryManager
                                        .getInstanceFor(connection);

                                if (sdm == null) {
                                    sdm = new ServiceDiscoveryManager(
                                            connection);
                                    Log.e("service discovery", "SDM");
                                    sdm.addFeature("http://jabber.org/protocol/disco#info");

                                    sdm.addFeature("jabber:iq:privacy");
                                }
                                configureProviderManager(connection);
                                FileTransferNegotiator.IBB_ONLY = true;
                                FileTransferNegotiator.setServiceEnabled(connection, true);
                                mFileTransferManager = new FileTransferManager(
                                        connection);
                                /*
                                 * OutgoingFileTransfer transfer =
                                 * mFileTransferManager
                                 * .createOutgoingFileTransfer
                                 * ("98c6d889473a6fae@pc/Smack");
                                 */
                                String to = connection.getRoster()
                                        .getPresence("98c6d889473a6fae@pc")
                                        .getFrom();
                                final OutgoingFileTransfer transfer = mFileTransferManager
                                        .createOutgoingFileTransfer(to);
                                File file = new File(filepath);

                                try {
                                    configureProviderManager(connection);
                                    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();

                            }
                            d.dismiss();
                        }
                    });

configureProviderManager(connection) 的实现在哪里? - Devendra Singh
请提供完整的configureProviderManager(connection)方法,我在使用这个方法时遇到了问题,请分享一下。 - habib ullah

0

我曾经遇到过同样的问题,我调查了 stanza 并以这种方式解决了它。

许多人在 jid 中使用"/Smack""/Resource"作为资源部分,但也可以配置另一种方式。

资源路径随着用户每次出现的更改而改变。假设我们想将图像发送给此用户:"user1@mydomain"

您必须向此 jid 添加"/Resource"部分,它变成了这样:user1@mydomain/Resource

但是/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)
transfer.sendFile(new File("DirectoryPath"), "Description");

这就是我如何解决在Smack和Openfire上的文件传输问题。

在您的情况下,像这样形成 jid

String to = connection.getRoster().getPresence("98c6d889473a6fae@pc").getFrom();
String Resource = connection.getRoster().getPresence("98c6d889473a6fae@pc").getFrom().getResourceOrEmpty().toString();
OutgoingFileTransfer transfer = mFileTransferManager.createOutgoingFileTransfer(to + "/" + resource);

此外还要提到,您必须在您的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");

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