在android中使用Smack的ejabberd连接给出连接超时错误

Posted

技术标签:

【中文标题】在android中使用Smack的ejabberd连接给出连接超时错误【英文标题】:ejabberd connection using Smack in android giving connection timed out error 【发布时间】:2018-08-06 08:03:39 【问题描述】:

您好,我们已经从this 下载了 ejabberd。域是localhost,我们已将 xmppDomain 设置为我计算机的 IP 地址。我已使用以下代码进行连接

    public static final String XMPP_DOMAIN = "localhost";
    public static final String XMPP_HOST = "10.0.2.2";//kept for emaulator
    //public static final String XMPP_HOST = "192.168.1.152"; //ip of my pc
    public static final int XMPP_PORT = 5222;
    public static final String XMPP_RESOURCE = "xmppdemo";
    public static final boolean XMPP_DEBUG = true;

      private void initialiseConnection() throws IOException, InterruptedException, XMPPException, SmackException 
        InetAddress addr = InetAddress.getByName(Constants.XMPP_HOST);
        DomainBareJid serviceName = JidCreate.domainBareFrom(Constants.XMPP_DOMAIN);

        XMPPTCPConnectionConfiguration.Builder config = XMPPTCPConnectionConfiguration
                .builder();
        config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
        config.setXmppDomain(serviceName);
        config.setHostAddress(addr);
        config.setPort(Constants.XMPP_PORT);
        config.setDebuggerEnabled(Constants.XMPP_DEBUG);
        config.setResource(Constants.XMPP_RESOURCE);
        connection = new XMPPTCPConnection(config.build());
        connection.addConnectionListener(mConnectionListener);
        connection.addAsyncStanzaListener(mStanzaListener, new StanzaFilter() 
            @Override
            public boolean accept(Stanza stanza) 
                //You can also return only presence packets, since we are only filtering presences
                return true;
            
        );

        Roster.setDefaultSubscriptionMode(Roster.SubscriptionMode.manual);
        roster = Roster.getInstanceFor(connection);
        roster.addRosterListener(mRoasterListener);


    

     public void connect() 

        @SuppressLint("StaticFieldLeak") AsyncTask<Void, Void, Boolean> connectionThread = new AsyncTask<Void, Void, Boolean>() 
            @Override
            protected synchronized Boolean doInBackground(Void... arg0) 
                //There is no point in reconnecting an already established connection. So abort, if we do
                if (connection.isConnected())
                    return false;

                //We are currently in "connection" phase, so no requests should be made while we are connecting.
                isconnecting = true;

                if (isToasted)
                    new Handler(Looper.getMainLooper()).post(new Runnable() 
                        @Override
                        public void run() 
                            Toast.makeText(service, "connecting....", Toast.LENGTH_LONG).show();
                        
                    );

                if (debug) Log.d(TAG, "connecting....");

                try 
                    connection.connect();

                    /**
                     * Set delivery receipt for every Message, so that we can confirm if message
                     * has been received on other end.
                     *
                     * @NOTE: This feature is not yet implemented in this example. Maybe, I'll add it later on.
                     * Feel free to pull request to add one.
                     *
                     * Read more about this: http://xmpp.org/extensions/xep-0184.html
                     **/

                    DeliveryReceiptManager dm = DeliveryReceiptManager.getInstanceFor(connection);
                    dm.setAutoReceiptMode(DeliveryReceiptManager.AutoReceiptMode.always);
                    dm.addReceiptReceivedListener(new ReceiptReceivedListener() 
                        @Override
                        public void onReceiptReceived(Jid fromJid, Jid toJid, String receiptId, Stanza receipt) 

                        

//                        @Override
//                        public void onReceiptReceived(final String fromid,
//                                                      final String toid, final String msgid,
//                                                      final Stanza packet) 
//
//                        
                    );
                    connected = true;

                 catch (IOException e) 
                    service.onConnectionClosed();
                    if (isToasted)
                        new Handler(Looper.getMainLooper())
                                .post(new Runnable() 

                                    @Override
                                    public void run() 
                                        Toast.makeText(service, "IOException: ", Toast.LENGTH_SHORT).show();
                                    
                                );
                    if (debug) Log.e(TAG, "IOException: " + e.getMessage());
                 catch (SmackException e) 
                    service.onConnectionClosed();
                    if (isToasted)
                        new Handler(Looper.getMainLooper()).post(new Runnable() 
                            @Override
                            public void run() 
                                Toast.makeText(service, "SMACKException: ", Toast.LENGTH_SHORT).show();
                            
                        );
                    if (debug) Log.e(TAG, "SMACKException: " + e.getMessage());
                 catch (XMPPException e) 
                    service.onConnectionClosed();
                    if (isToasted)
                        new Handler(Looper.getMainLooper()).post(new Runnable() 
                            @Override
                            public void run() 
                                Toast.makeText(service, "XMPPException: ", Toast.LENGTH_SHORT).show();
                            
                        );
                    if (debug) Log.e(TAG, "XMPPException: " + e.getMessage());
                 catch (InterruptedException e) 
                    e.printStackTrace();
                

                //Our "connection" phase is now complete. We can tell others to make requests from now on.
                return isconnecting = false;
            
        ;
        connectionThread.execute();
    
     //Signup to server
    public void Signup(SignupModel signupModel) 
        XMPPError.Condition condition = null;
        boolean errors = false;
        String errorMessage = "";

        String mUsername = signupModel.getUsername();
        String mPassword = signupModel.getPassword();

        boolean isPasswordValid = signupModel.checkPassword();
        boolean areFieldsValid = signupModel.validateFields();

        if (!isPasswordValid) 
            errors = true;
            errorMessage = Constants.SIGNUP_ERR_INVALIDPASS;
        

        if (!areFieldsValid) 
            errors = true;
            errorMessage = Constants.SIGNUP_ERR_FIELDERR;
        

        if (errors) 
            service.onSignupFailed(errorMessage);
            return;
        

        new Thread(new Runnable() 
            @Override
            public void run() 
                if (!connected && !isconnecting) connect();
            
        ).start();

        try 
//            final AccountManager accountManager = AccountManager.getInstance(connection);
//
//
//            accountManager.createAccount(Localpart.from(mUsername), mPassword);


            AccountManager accountManager = AccountManager.getInstance(connection);
            accountManager.sensitiveOperationOverInsecureConnection(true);
            accountManager.createAccount(Localpart.from(mUsername), mPassword);

         catch (XMPPException | SmackException e) 

            e.printStackTrace();
            if (debug) Log.e(TAG, "Username: " + mUsername + ",Password: " + mPassword);

            if (e instanceof XMPPException.XMPPErrorException) 
                condition = ((XMPPException.XMPPErrorException) e).getXMPPError().getCondition();
            

            if (condition == null) 
                condition = XMPPError.Condition.internal_server_error;
            
         catch (InterruptedException e) 
            e.printStackTrace();
         catch (XmppStringprepException e) 
            e.printStackTrace();
        

        if (condition == null) 
            service.onSignupSuccess();
         else 
            switch (condition) 
                case conflict:
                    errorMessage = Constants.SIGNUP_ERR_CONFLICT;
                    break;
                case internal_server_error:
                    errorMessage = Constants.SIGNUP_ERR_SERVER_ERR;
                    break;
                default:
                    errorMessage = condition.toString();
                    break;

            

            service.onSignupFailed(errorMessage);
        
    

    //Login to server
    public void login() 
        try 

            new Thread(new Runnable() 
                @Override
                public void run() 
                    if (!connected && !isconnecting) connect();
                
            ).start();

            if (debug) Log.i(TAG, "User " + userId + userPassword);

            connection.login(userId, userPassword);

            if (debug) Log.i(TAG, "Yey! We're logged in to the Xmpp server!");

            service.onLoggedIn();
         catch (XMPPException | SmackException | IOException e) 

            service.onLoginFailed();
            if (debug) e.printStackTrace();
         catch (InterruptedException e) 
            e.printStackTrace();
        
    

当我运行此代码时,我收到以下异常(尝试从模拟器运行时)

SMACKException: The following addresses failed: '10.0.2.2:5222' failed because: /10.0.2.2 exception: java.net.SocketTimeoutException: failed to connect to /10.0.2.2 (port 5222) from /192.168.232.2 (port 34922) after 30000ms

当我尝试从我的设备运行时,我将 HOST_NAME 作为我电脑的 IP 地址,但随后我收到以下错误

E/XMPPHandler: SMACKException: The following addresses failed: '192.168.1.152:5222' failed because: /192.168.1.152 exception: java.net.SocketTimeoutException: connect timed out

当我在我的电脑上安装 ejabberd 时,我收到了以下访问控制列表页面 .. 我应该改变什么吗?还是遗漏了什么?

【问题讨论】:

【参考方案1】:

我也有这个问题。我不知道为什么,但是 windows 上的 ejabberd 服务器无法正常工作。我尝试在 linux 和 mac 上安装服务器,它工作正常。但在 windows 版本上总是得到 SocketTimeoutException。

【讨论】:

如果您的问题解决了,请接受并投票。谢谢。 感谢您的回复,但您能否分享您尝试在 MAC 上安装 ejabberd 的链接。因为我尝试过但没有成功。 我使用this page 来安装先决条件。成功执行brew install git erlang autoconf automake expat openssl libyaml libiconv sqlite brew 后,您可以轻松安装和运行ejabberd。【参考方案2】:

我有类似的问题。我在 Windows 10 中安装了 openfire serevr。 我的代码是

DomainBareJid xmppServiceDomain = JidCreate.domainBareFrom("desktop-urvfr83");
            //DomainBareJid xmppServiceDomain = JidCreate.domainBareFrom("192.168.1.3");
            InetAddress addr = InetAddress.getByName("192.168.1.3");

            XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder()
                    .setUsernameAndPassword("alir", "111111")
                    .setHostAddress(addr)
                    .setResource("phonn")
                    .setXmppDomain(xmppServiceDomain)
                    .setSecurityMode(ConnectionConfiguration.SecurityMode.disabled)
                    .setPort(5222)
                    .build();

但它无法连接。当我禁用防火墙时,它可以正常工作并连接。

【讨论】:

以上是关于在android中使用Smack的ejabberd连接给出连接超时错误的主要内容,如果未能解决你的问题,请参考以下文章

使用 Ejabberd 和 Smack for Android 创建群聊功能的正确方法是啥?

Smack Android 客户端无法连接到 ejabberd 服务器

smack / ejabberd 连接超时

使用 EJABBERD-BUSINESS 版本在 SMACK 中恢复流后读取“重新绑定”数据包

使用 Smack 在 ejabberd 上创建用户时出现异常

如何使用 smack 库从客户端搜索 ejabberd 服务器上的注册用户?