3
votes

I am trying to send a file through chat using openfire on the server and the smack java library.

This is the output I get:

Status :: Error Error :: null Exception :: service-unavailable(503) Is it done? true

Here are my sender and receiver functions:

public void fileTransfer(String fileName, String destination) throws XMPPException {

    // Create the file transfer manager
    FileTransferManager manager = new FileTransferManager(connection);
    FileTransferNegotiator.setServiceEnabled(connection,true);
    // Create the outgoing file transfer
    OutgoingFileTransfer transfer = manager.createOutgoingFileTransfer(destination);

    // Send the file
    transfer.sendFile(new File(fileName), "You won't believe this!");
    try {
        Thread.sleep(10000);
    }
    catch(Exception e){}
    System.out.println("Status :: " + transfer.getStatus() + " Error :: " + transfer.getError() + " Exception :: " + transfer.getException());
    System.out.println("Is it done? " + transfer.isDone());
}

public void fileReceiver(final boolean accept, final String fileName) {
    // Create the file transfer manager
    final FileTransferManager manager = new FileTransferManager(connection);

    // Create the listener
    manager.addFileTransferListener(new FileTransferListener() {
          public void fileTransferRequest(FileTransferRequest request) {
              // broadcast something here. Wheather users want to accept file
                // Check to see if the request should be accepted
                if(accept) {
                      // Accept it
                      IncomingFileTransfer transfer = request.accept();
                  try {
                      transfer.recieveFile(new File(fileName));
                      System.out.println("File " + fileName + "Received Successfully");
                      //InputStream input = transfer.recieveFile();
                  } catch (XMPPException ex) {
                      Logger.getLogger(XmppManager.class.getName()).log(Level.SEVERE, null, ex);
                  }
                } else {
                      // Reject it
                      request.reject();
                }
          }
    });
  }
1
why is this question downvoted? Anyway, have You solved the problem? And which smack do you use, because it seems You don´t use the latest version of Smack..Opiatefuchs
No. I haven't solved the problem. I use Smack 3.1.0. Does the version matter?user2424586
of Course, the new Version 4.1 has many bugfixes, more flexibility and is ready for Android (which doesn´t matter in Your case). But also, I haven´t get it to send Files via File transfer. The only thing You have to watch is, if You use a free xmpp server which is not yours, the server has to support file transfer. Not all servers do this...Opiatefuchs
@Opiatefuchs what types of bugfixes are done in smack 4.1?mubeen
many...don´t know exactly what is fixed, but some parts for connecting. There were lot of poeple having same problem like You, turning to 4.1 fixed it. See here: github.com/igniterealtime/Smack/wiki/… and also inside the community are helpful threads: community.igniterealtime.org/welcomeOpiatefuchs

1 Answers

2
votes

I had same problem, I investigated the stanza and solved it this way.

Many people use "/Smack" or "/Resource" as resource part in jid, but that can be done another way.

Resource path is changing with every presence changed of user. Lets say we want to send image to this user: "user1@mydomain"

You must add "/Resource" part to this jid and it become this: user1@mydomain/Resource

But /Resource path is changing with presence so you must follow every presence change to update resource path. Best way is to get user presence is in roster listener and in presencheChanged() method you get last user resource part like this:

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
                    //...
                }
            });
}

Resource string will be some generated string like "6u1613j3kv" and jid will become:

user1@mydomain/6u1613j3kv

That means that you must create your outgoing transfer like this:

EntityFullJid jid = JidCreate.entityFullFrom("user1@mydomain/6u1613j3kv"); 
OutgoingFileTransfer transfer = manager.createOutgoingFileTransfer(jid)
transfer.sendFile(new File("DirectoryPath"), "Description");

And that is how i have solved my problem with file transfer on smack and Openfire.

In your case jid is destination.

Also to mention you must add following properties in your Openfire server:

xmpp.proxy.enabled - true
xmpp.proxy.externalip - MY_IP_ADDRESS
xmpp.proxy.port - 7777

Just to mention, I am using Openfire 4.0.2 and Smack 4.2.2.

Also this can be configured the easy way, just set the resource on

XMPPTCPConnectionConfiguration.Builder .

like

XMPPTCPConnectionConfiguration.Builder configurationBuilder = 
XMPPTCPConnectionConfiguration.builder(); 

configurationBuilder.setResource("yourResourceName");