在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 服务器
使用 EJABBERD-BUSINESS 版本在 SMACK 中恢复流后读取“重新绑定”数据包