Asmack file transfer progress always at 0.0

2019-02-21 01:21发布

问题:

Hi there i am using asmack-android-19-0.8.10.jar and openfire to develop file transfer. i refered to harryjoy.me but i have problems when sending the file where transfer.getProgress() always return 0.0. below is the log file.

Send File :

05-06 15:42:35.669: D/SMACK(25533): 03:42:35 PM SENT (1103132248): 
<iq id="7dnrX-23" to="lala@kaoru-pc/Smack" from="lolo@kaoru-pc/Smack" type="set">
    <si xmlns="http://jabber.org/protocol/si" id="jsi_8243824082816759940" mime-type="image/jpeg" profile="http://jabber.org/protocol/si/profile/file-transfer">
        <file xmlns="http://jabber.org/protocol/si/profile/file-transfer" name="pic_1399362155598.jpg" size="94630" >
            <desc>lolo</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>

05-06 15:42:35.719: D/SMACK(25533): 03:42:35 PM RCV  (1103132248): 
<iq id="7dnrX-23" to="lolo@kaoru-pc/Smack" from="lala@kaoru-pc/Smack" type="result">
    <si xmlns="http://jabber.org/protocol/si">
        <feature xmlns="http://jabber.org/protocol/feature-neg">
            <x xmlns="jabber:x:data" type="submit">
                <field var="stream-method">
                    <value>http://jabber.org/protocol/bytestreams</value>
                    <value>http://jabber.org/protocol/ibb</value>
                </field>
            </x>
        </feature>
    </si>
</iq>

05-06 15:42:35.719: D/SMACK(25533): 03:42:35 PM SENT (1103132248): 
<iq id="7dnrX-24" to="lala@kaoru-pc/Smack" type="get">
    <query xmlns="http://jabber.org/protocol/disco#info"></query>
</iq>

05-06 15:42:40.713: D/SMACK(25533): 03:42:40 PM SENT (1103132248): 
<iq id="7dnrX-25" to="lala@kaoru-pc/Smack" type="set">
    <open xmlns="http://jabber.org/protocol/ibb" block-size="4096" sid="jsi_8243824082816759940" stanza="iq"/>
</iq>
05-06 15:42:40.744: D/SMACK(25533): 03:42:40 PM RCV  (1103132248): 
<iq id="7dnrX-25" to="lolo@kaoru-pc/Smack" from="lala@kaoru-pc/Smack" type="result"/>

05-06 15:42:40.754: D/SMACK(25533): 03:42:40 PM SENT (1103132248): 
<iq id="7dnrX-26" to="lala@kaoru-pc/Smack" type="set">
    <data xmlns="http://jabber.org/protocol/ibb" seq="0" sid="jsi_8243824082816759940">
        ** Some data **

05-06 15:42:45.758: D/SMACK(25533): 03:42:45 PM SENT (1103132248): 
<iq id="7dnrX-27" to="lala@kaoru-pc/Smack" type="set">
    <data xmlns="http://jabber.org/protocol/ibb" seq="0" sid="jsi_8243824082816759940">
        ** Some data **

05-06 15:42:50.763: D/SMACK(25533): 03:42:50 PM SENT (1103132248): 
<iq id="7dnrX-28" to="lala@kaoru-pc/Smack" type="set">
<close xmlns="http://jabber.org/protocol/ibb" sid="jsi_8243824082816759940"/></iq>

Receive file :

    05-06 04:53:06.409: D/SMACK(1324): 04:53:06 AM RCV  (1384483676): 
<iq id="0cxQ1-38" to="lala@kaoru-pc/Smack" from="lolo@kaoru-pc/Smack" type="set">
    <si xmlns="http://jabber.org/protocol/si" id="jsi_4342883008583481067" mime-type="image/jpeg" profile="http://jabber.org/protocol/si/profile/file-transfer">
        <file xmlns="http://jabber.org/protocol/si/profile/file-transfer" name="pic_1399351997548.jpg" size="93096"><desc>lolo</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>
05-06 04:53:06.413: D/SMACK(1324): 04:53:06 AM SENT (1384483676): 
<iq id="0cxQ1-38" to="lolo@kaoru-pc/Smack" from="lala@kaoru-pc/Smack" type="result">
<si xmlns="http://jabber.org/protocol/si">
    <feature xmlns="http://jabber.org/protocol/feature-neg">
        <x xmlns="jabber:x:data" type="submit">
            <field var="stream-method">
                <value>http://jabber.org/protocol/bytestreams</value>
                <value>http://jabber.org/protocol/ibb</value>
            </field>
        </x>
    </feature>
</si>
</iq>

05-06 04:53:06.429: D/SMACK(1324): 04:53:06 AM RCV  (1384483676): 
<iq id="0cxQ1-39" to="lala@kaoru-pc/Smack" type="get" from="lolo@kaoru-pc/Smack">
    <query xmlns="http://jabber.org/protocol/disco#info"/>
</iq>

05-06 04:53:11.433: D/SMACK(1324): 04:53:11 AM RCV  (1384483676): 
<iq id="0cxQ1-40" to="lala@kaoru-pc/Smack" type="set" from="lolo@kaoru-pc/Smack">
    <open xmlns="http://jabber.org/protocol/ibb" block-size="4096" sid="jsi_4342883008583481067" stanza="iq"/>
</iq>

05-06 04:53:11.441: D/SMACK(1324): 04:53:11 AM SENT (1384483676): 
<iq id="0cxQ1-40" to="lolo@kaoru-pc/Smack" from="lala@kaoru-pc/Smack" type="result">
</iq>

05-06 04:53:11.485: D/SMACK(1324): 04:53:11 AM RCV  (1384483676): 
<iq id="0cxQ1-41" to="lala@kaoru-pc/Smack" type="set" from="lolo@kaoru-pc/Smack">
<data xmlns="http://jabber.org/protocol/ibb" seq="0" sid="jsi_4342883008583481067">
** Some data **

05-06 04:53:16.545: D/SMACK(1324): 04:53:16 AM RCV  (1384483676): 
<iq id="0cxQ1-42" to="lala@kaoru-pc/Smack" type="set" from="lolo@kaoru-pc/Smack">
<data xmlns="http://jabber.org/protocol/ibb" seq="0" sid="jsi_4342883008583481067">      ** Some data **

05-06 04:53:16.545: D/SMACK(1324): 04:53:16 AM RCV  (1384483676): 
** Some data **</data></iq>

05-06 04:53:21.501: D/SMACK(1324): 04:53:21 AM RCV  (1384483676): 
<iq id="0cxQ1-43" to="lala@kaoru-pc/Smack" type="set" from="lolo@kaoru-pc/Smack">
    <close xmlns="http://jabber.org/protocol/ibb" sid="jsi_4342883008583481067"/>
</iq>

This is the error code i got from transfer.getException for sendFile();

05-07 09:08:01.917: D/Error(12587): chatRoom.java at line 892 : error writing to output stream: 
05-07 09:08:01.917: D/Error(12587):   -- caused by: java.io.IOException: Error while closing stream: No response from server.

**** UPDATED ****

Sender.java

try {
                    FileTransferManager manager = new FileTransferManager(OpenFireAuthenticateService.connection);
                    FileTransferNegotiator.getInstanceFor(OpenFireAuthenticateService.connection);
                    FileTransferNegotiator.setServiceEnabled(OpenFireAuthenticateService.connection,true);

                    // Create the outgoing file transfer
                    OutgoingFileTransfer transfer = manager.createOutgoingFileTransfer(userName+"@"+OpenFireAuthenticateService.serverName + "/Smack");

                    // Send the file                
                    transfer.sendFile(new File(path), OpenFireAuthenticateService.hostName.substring(0, OpenFireAuthenticateService.hostName.indexOf("@")));

                    while(!transfer.isDone()) {

                        if(transfer.getStatus().equals(org.jivesoftware.smackx.filetransfer.FileTransfer.Status.error)) {
                            Log.d("Error","chatRoom.java at line 879 : "+transfer.getError().toString());
                        } else if (transfer.getStatus().equals(org.jivesoftware.smackx.filetransfer.FileTransfer.Status.cancelled)
                                            || transfer.getStatus().equals(org.jivesoftware.smackx.filetransfer.FileTransfer.Status.refused)) {
                               Log.d("Error","chatRoom.java at line 882 : "+transfer.getError().toString());
                        }
                        try {
                            Log.d("TEST", "STATUS: " + transfer.getStatus().toString() + " SIZE: " + new File(path).length() + " PROGRESS: " + transfer.getProgress() + " StreamID : "+transfer.getStreamID());
                            Thread.sleep(1000L);
                        } catch (InterruptedException e) {
                               Log.d("Error","chatRoom.java at line 887 : "+e.toString());
                        }
                    }

                    if(transfer.getStatus().equals(org.jivesoftware.smackx.filetransfer.FileTransfer.Status.refused)) {
                        Log.d("Error","chatRoom.java at line 946 : "+transfer.getException());
                    }
                    else if(transfer.getStatus().equals(org.jivesoftware.smackx.filetransfer.FileTransfer.Status.error)) {
                        Log.d("Error","chatRoom.java at line 949 : "+transfer.getException());
                    }
                    else if(transfer.getStatus().equals(org.jivesoftware.smackx.filetransfer.FileTransfer.Status.cancelled)){
                        Log.d("Error","chatRoom.java at line 952 : "+transfer.getException());
                    } else {
                                Log.d("TEST","Success");
                    }

                } catch (XMPPException e) {
                    Log.d("Error","chatRoom.java at line 895 : "+e.toString());
                }

Receiver.java

ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection);
                if (sdm == null){
                    sdm = ServiceDiscoveryManager.getInstanceFor(connection);
                }
                sdm.addFeature("http://jabber.org/protocol/disco#info");
                sdm.addFeature("jabber:iq:privacy");
                sdm.addFeature("http://jabber.org/protocol/disco#items");

                FileTransferManager manager = new FileTransferManager(connection);
                FileTransferNegotiator.getInstanceFor(connection);
                FileTransferNegotiator.setServiceEnabled(connection,true);
                manager.addFileTransferListener(new ServiceFileTransferListener(context));

ServiceFileTransferListener.java

try {               
                File f = new File(filePath);
                IncomingFileTransfer transfer = request.accept();

                transfer.recieveFile(f);
                while(!transfer.isDone()) {
                       try{
                          Thread.sleep(1000);
                          Log.d("TEST", "STATUS: " + transfer.getStatus().toString() + " SIZE: " + f.length() + " Stream ID : " + transfer.getStreamID());
                       }catch (Exception e) {
                          Log.e("Error", "ServiceFileTransferListener.java at line 61 : "+e.getMessage());
                       }
                       if(transfer.getStatus().equals(Status.error)) {
                          Log.e("Error ", "ServiceFileTransferListener.java at line 72 : "+ transfer.getStatus());
                       }
                       if(transfer.getException() != null) {
                          Log.e("Error","ServiceFileTransferListener.java at line 75 : "+transfer.getException().getStackTrace());
                       }
                }
                Log.d("TEST","Received : "+request.getFileName() + " from " +request.getRequestor() + " File Size : "+request.getFileSize());
                Log.d("TEST","Status : "+transfer.getStatus());
                groupChatName = request.getRequestor().substring(0, request.getRequestor().indexOf("@"));   
                msgHeader = request.getFileName().substring(0, 3);
                msgBody = request.getFileName();
                memberName = "from";

            } 
            catch(XMPPException e) {
                Log.d("Error","ServiceFileTransferListener.java at line 79 : "+ e.toString());
            }

回答1:

Implementation looks buggy, e.g.

<feature xmlns="http://jabber.org/protocol/feature-neg">
        <x xmlns="jabber:x:data" type="submit">
            <field var="stream-method">
                <value>http://jabber.org/protocol/bytestreams</value>
                <value>http://jabber.org/protocol/ibb</value>
            </field>
        </x>
    </feature>

is wrong reply, because XEP-0095 say:

If acceptable the Receiver MUST select one of the presented stream types to use.

Try to use only one stream method and/or submit bugreport to Smack.



回答2:

First, thanks for the detailed question. That makes it easy to get an idea what could be wrong. While vitalyster is right, the stanza is a violation of the spec, I don't think this is the cause for the problem.

What looks wrong is that we don't see any result IQs for the set IQs that carry a data element, ie the stanza of Example 7 in XEP-47 is missing. That's all I can say with the provided information. I suggest you grab a debugger to find the root cause. Good that (a)Smack is open source

Edit: You call SmackAndroid.init(Context) as aSmacks README tells you to do, or not?