问题
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?
来源:https://stackoverflow.com/questions/23489617/asmack-file-transfer-progress-always-at-0-0