使用Smack API在使用Openfrie的transer文件时获取错误

时间:2017-11-06 05:01:37

标签: android openfire smack

我想传输文件,例如。来自Openfire with Smack Api的图像或视频。
但我每次都收到错误代码503服务不可用 我的编码

public void  onConnectionEstablished(){
    fileTransferManager = FileTransferManager.getInstanceFor(connection);
    OutgoingFileTransfer.setResponseTimeout(30000);
    addFileTransferListener();
}


public void sendImage(File file, String to) throws SmackInvocationException {
    if (fileTransferManager == null || !isConnected()) {
        throw new SmackInvocationException("server not connected");
    }

    EntityFullJid fullJid;



    OutgoingFileTransfer transfer = fileTransferManager.createOutgoingFileTransfer(getFullJid(to));

    try {

        transfer.sendFile(file, file.getName());
    } catch (Exception e) {
        Log.e(LOG_TAG, "send file error");
        throw new SmackInvocationException(e);
    }

    while(!transfer.isDone()) {
        if(transfer.getStatus().equals(FileTransfer.Status.refused) || transfer.getStatus().equals(FileTransfer.Status.error)
                || transfer.getStatus().equals(FileTransfer.Status.cancelled)){
            throw new SmackInvocationException("send file error, " + transfer.getError());
        }
    }

    Log.d(LOG_TAG, "send file status: " + transfer.getStatus());
    if(transfer.getStatus().equals(FileTransfer.Status.refused) || transfer.getStatus().equals(FileTransfer.Status.error)
            || transfer.getStatus().equals(FileTransfer.Status.cancelled)){
        throw new SmackInvocationException("send file error, " + transfer.getError());
    }
}

private void addFileTransferListener() {

    fileTransferManager.addFileTransferListener(new FileTransferListener() {
        public void fileTransferRequest(final FileTransferRequest request) {
            new Thread() {
                @Override
                public void run() {


                    IncomingFileTransfer transfer = request.accept();
                    String fileName = String.valueOf(System.currentTimeMillis());
                    File file = new File(FileUtils.getReceivedImagesDir(context), fileName + FileUtils.IMAGE_EXTENSION);
                    try {
                        transfer.recieveFile(file);

                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    catch (SmackException e) {
                        Log.e(LOG_TAG, "receive file error", e);
                        return;
                    }

                    while (!transfer.isDone()) {
                        if(transfer.getStatus().equals(FileTransfer.Status.refused) || transfer.getStatus().equals(FileTransfer.Status.error)
                                || transfer.getStatus().equals(FileTransfer.Status.cancelled)){
                            Log.e(LOG_TAG, "receive file error, " + transfer.getError());
                            return;
                        }
                    }
                }
            }.start();
        }
    });
}

我的日志

<iq type="error" id="Z6hyN-147" from="7665935694@ec2-18-221-73-31.us-east-2.compute.amazonaws.com/smack" to="8094772915@ec2-18-221-73-31.us-east-2.compute.amazonaws.com/smack"><si xmlns="http://jabber.org/protocol/si" id="jsi_1095486335648182993" mime-type="image/jpeg" profile="http://jabber.org/protocol/si/profile/file-transfer"><file xmlns="http://jabber.org/protocol/si/profile/file-transfer" name="1509942029217.jpg" size="830807"><desc>1509942029217.jpg</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><error code="503" type="cancel"><service-unavailable xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/></error></iq>


我观察到一件事,当用户发送者和接收者都在同一个网络上时,就不会出现错误。

Openfire服务器中有一个文件传输设置,如下所示。我不知道它的含义以及如何配置它。

enter image description here

我在stackoverflow上看到了很多问题,但没有得到答案 请帮帮我。谢谢

1 个答案:

答案 0 :(得分:0)

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

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

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

你必须在这个jid中添加“/ Resource”或“/ Smack”部分,它会变为: 的 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
                    //...
                }
            });
}

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

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

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

在你的情况下:     String to =“user1 @ mydomain / 6u1613j3kv”;     EntityFullJid fullJid = JidCreate.entityFullFrom(to);     OutgoingFileTransfer transfer = fileTransferManager.createOutgoingFileTransfer(fullJid);

6u1613j3kv 会在每次更改时生成字符串。

这就是我在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。