如何在android中使用asmack配置文件传输连接?

时间:2016-01-07 10:31:40

标签: android xmpp smack asmack

在我的Android应用程序中,我最初使用server_nm和5222端口进行xmpp连接并完成单个聊天消息的发送和接收,但在文件传输时,如何配置与用于文件传输的proxy_server和7777端口的连接?

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 个答案:

答案 0 :(得分:0)

不要依赖于使用sSck / Smack进行XMPP文件传输,因为它很棒。相反,您可以创建一个插件,将文件上传到服务器,成功上传文件后,将文件的绝对URL发送给收件人,以便他/她可以从那里下载文件。

希望这有效!

答案 1 :(得分:0)

如果你仍然希望直接通过smack传输文件,那么基本上我有太多的选择,就我理解API而言。

1。 首先,您可以使用带内传输,即通过

启用
FileTransferNegotiator.IBB_ONLY = true;

这会将您的文件作为base64编码消息发送,与发送普通消息包的方式相同。

  1. 第二个选项是使用流媒体代理。这个更快,因为它不需要将文件编码/解码为base64,而是直接传输数据。这两个设备都与代理服务器连接并在此上共享数据。
  2. 要配置流代理,您必须在服务器端配置它,并将Providers添加到客户端连接(这应该在最新的asmack库上自动完成)。

    我使用ejabberd服务和mod_proxy65配置了这样的设置Mod_proxy65

    添加到您的/etc/ejabberd/ejabberd.yml,您的IP地址和主机应该与您正在使用的服务相匹配。

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

    然后允许防火墙在这个端口上进行通信,你应该好好去。

    但是,我发现,只有文件传输功能正常,如果两个客户端都处于“可用”状态(如果其中任何一个处于另一个状态),则发送方会收到“service-unavailabe”错误。