1
votes

In My Android application I get xmpp connection initially using server_nm and 5222 port on login and done single chat message send and receive,but at time of file transfer, How I configure connection with proxy_server and 7777 port which use for file transfer?

public class XmppManager {

                private static final int packetReplyTimeout = 500; // millis
                private String server=server_nm;
                private int port=5222;


                private ConnectionConfiguration config;
                private XMPPConnection connection;

                String group_name,userid;

                private ChatManager chatManager;
                private MessageListener messageListener;
                private Handler mHandler;
                PacketFilter filter;
                Message message;
                Context context;
                 public static boolean IBB_ONLY = (System.getProperty("ibb") != null);//true;
                 protected static final String STREAM_DATA_FIELD_NAME = "stream-method";

                 private  StreamNegotiator byteStreamTransferManager;
                 private  StreamNegotiator inbandTransferManager;


                // constructor
                public XmppManager(String server, int port) {
                    this.server = server;
                    this.port = port;

                }

                // to initialize connection
                public void init(Context c) throws XMPPException {

                    System.out.println(String.format(
                            "Initializing connection to server %1$s port %2$d", server,
                            port));

                    SmackConfiguration.setPacketReplyTimeout(50000);

                    config = new ConnectionConfiguration(server, port);
                    config.setSASLAuthenticationEnabled(false);
                    config.setSecurityMode(SecurityMode.disabled);

                    // group chat invitation
                    ProviderManager.getInstance().addExtensionProvider("x",
                            "http://jabber.org/protocol/muc#user",
                            new GroupChatInvitation.Provider());
                    // offline msgtime
                    ProviderManager.getInstance().addExtensionProvider("x",
                            "jabber:x:delay", new DelayInformationProvider());

                    //file transfer method
                    ProviderManager.getInstance().addIQProvider("query","http://jabber.org/protocol/bytestreams", new BytestreamsProvider());
                    ProviderManager.getInstance().addIQProvider("query","http://jabber.org/protocol/disco#items", new DiscoverItemsProvider());
                    ProviderManager.getInstance().addIQProvider("query","http://jabber.org/protocol/disco#info", new DiscoverInfoProvider());
                    ProviderManager.getInstance().addIQProvider("si","http://jabber.org/protocol/si", new StreamInitiationProvider());
                    ProviderManager.getInstance().addIQProvider("open","http://jabber.org/protocol/ibb", new OpenIQProvider());
                    ProviderManager.getInstance().addIQProvider("close","http://jabber.org/protocol/ibb", new CloseIQProvider());
                    ProviderManager.getInstance().addExtensionProvider("data","http://jabber.org/protocol/ibb", new DataPacketProvider());

                    // v-card integration
                    ProviderManager.getInstance().addIQProvider("vCard", "vcard-temp", new VCardProvider());

                    connection = new XMPPConnection(config);
                    connection.connect();

                    System.out.println("Connected: " + connection.isConnected());

                    chatManager = connection.getChatManager();
                    context = c;
                    Intent i = new Intent(context, MyService.class);
                    context.startService(i);

                }

                // login to xmpp server
                public void performLogin(String username, String password,String resource)
                        throws XMPPException {
                    if (connection != null && connection.isConnected()) {

                        System.out.println("connection on presence send" + connection.isConnected() + " " + username + " " + password);
                        connection.login(username, password,resource);
                        setStatus(true, "Online");

                         Presence presence = new Presence(Presence.Type.available);  
                         connection.sendPacket(presence);  

                    }
                }

          //using this code I try to send file

        public void sendfileafterresponse(String filenm,String filereceiverid )
            {
                FileTransferNegotiator.IBB_ONLY = true;
                this.setServiceEnabled(connection, true);
                FileTransferManager manager = new FileTransferManager(connection);
                OutgoingFileTransfer transfer = manager.createOutgoingFileTransfer(filereceiverid + "@chat.bobl.us/" + filereceiverid);
                File file = new File(filenm);
                try {
                    System.out.println("file send to" + filenm + filereceiverid);
                   transfer.sendFile(file, "test_file");
                } catch (XMPPException e) {
                   e.printStackTrace();
                }


                while(!transfer.isDone()) {
                   if(transfer.getStatus().equals(Status.error)) {
                      System.out.println("ERROR!!! " + transfer.getError());
                   } else if (transfer.getStatus().equals(Status.cancelled)
                                    || transfer.getStatus().equals(Status.refused)) {
                      System.out.println("Cancelled!!! " + transfer.getError());
                   }
                   try {
                      Thread.sleep(1000L);
                   } catch (InterruptedException e) {
                      e.printStackTrace();
                   }
                }
                if(transfer.getStatus().equals(Status.refused) || transfer.getStatus().equals(Status.error)
                 || transfer.getStatus().equals(Status.cancelled)){
                   System.out.println("refused cancelled error " + transfer.getError());
                } else {
                   System.out.println("Success");
                }
            }

        }
        }
2

2 Answers

1
votes

If you still want to transfer files via smack directly, you basically have too options, as far as I understand the API.

1. First you can use In Band transmission, that is enabled via

FileTransferNegotiator.IBB_ONLY = true;

This sends your file as base64 encoded message, the same way you are sending a normal message packet.

  1. The second option is to use a streaming proxy. This one is way faster since it does not need to encode / decode the file to base64 but transmitts the data directly. Both devices connnect to the proxy server and share data on this.

To configure a streaming proxy you have to configure it on the server side and add the Providers to your client side connection (this should be done automatically on the latest asmack library).

I configured such a setup using the ejabberd service and mod_proxy65 Mod_proxy65

add to your /etc/ejabberd/ejabberd.yml, your ip adress and host should match the service you are using.

 host: "proxy1.example.org"
    name: "File Transfer Proxy"
    ip: "200.150.100.1" 
    port: 7777

Then allow the firewall to communicate on this port, and you should be good to go.

However, I figured out, that the file transfer only is functional, if both clients are in the presence "available" if any of them is in another state, the sender receives "service- unavailabe" errors.

0
votes

Don't rely on XMPP file transfer using aSmack/Smack as it is buly. Instead you can create a plugin which will upload files to the server and after successfully uploading the files send the absolute url of the file to the recipient so that he/she can download the file from there.

Hope this works !