openfire+smack4.2.2构建即时通讯应用遇到的各种坑

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37692352/article/details/79058800

第一次写博客。

发现在搭建服务器,写代码的过程中等过程中,遇到了许多坑,费了许多时间。如果不记下来,会忘记许多。

正好现在新版smack的资料比较少,查的可费劲了还查不到需要的。

分享给大家。

首先,回顾下流程。

在官网下载openfire,spark,smack。openfire是开源的服务器,安装以后,搭建自己的服务器。具体步骤网上可以搜到。一般是正确的。在此,提两点,域名可以自己设置成自己想要的。域名就是指向本机外网IP的一个名字。本机IP可以通过cmd命令行,输入ipconfig来查询(ipv4对应的)。另外,连接数据库我是下载的MYSQL数据库。MYSQL数据库安装的时候,只安装server就可以。安装完了,用navicat工具打开mysql。新建一个数据库openfire(自己取名字),然后运行sql文件,找openfire目录下的openfire_mysql.sql。如图:

 

运行完了,就可以得到图中的那些表。

spark是客户端,可以通过它,登录自己的服务器。用来测试服务器能不能用的。这里有个问题就是域填什么。最开始看到真是感觉坑爹。最后发现是填服务器名,也就是上面提到的域名。

smack解压出来,是各种jar包,导入需要的到lib中并添加依赖关系。当然还有其他的jar包。如图:

 

 

前戏终于搞完了,可以写代码了。

然后我就卡在了连接服务器上面。由于最新版的smack又许多更新,以前的登录代码不能用了。官网呢,也不好查。找了半天,新版的是这样连接的。

public void run() {
    try {
        String server="xxxx"; \\xxxx代表本机IP,前面提到的。
        InetAddress addr = InetAddress.getByName("xxxx);
        XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder()
                .setUsernameAndPassword("admin","xxx") \\ 自己在服务器上设置的账号

.setHost(server) //it will be resolved by setHostAddress method
                .setPort(5222)
                .setSecurityMode(ConnectionConfiguration.SecurityMode.disabled)
.setDebuggerEnabled(true)
                .build();
        conn = new XMPPTCPConnection(config);

        conn.connect();
        conn.login();
        if(conn.isConnected()){
            Log.d("XMPP","Connected");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

出现了如图的错误:

没定义XMPP domaindomain是域名的意思。那就设置个域名吧。诶,域名不就是我前面说的那个自己设置的域名吗?不好意思,不是。似乎以前可以,现版本不是的,这也是坑了我不少时间的坑。不废话了,全部给出。如下

加上:

InetAddress addr = InetAddress.getByName("xxxx");
HostnameVerifier verifier = new HostnameVerifier() {
    @Override
    public boolean verify(String hostname, SSLSession session) {
        return false;
    }
};

DomainBareJid serviceName = JidCreate.domainBareFrom("xxxx");

 

.setXmppDomain(serviceName)//加在config下面的属性中。

.setServiceName(serviceName)

.setHostnameVerifier(verifier)
.setHostAddress(addr)

 

Ok.终于可以连接上了!

看似简单,但实际上卡了我许久。因为百度和谷歌都难以查到。

接下来,本文最后提到的一个坑点,也是卡我时间最长的。

登录写完了,那咱是不是得写注册啊。

思路是将连接openfire的代码写在一个服务中,然后,注册和登录的Activity分开。

看起来很简单。

继续写注册的呗。

public void onClick(View v) {
    conn1=binder.getAbstractXMPPConnection();
    AccountManager manager = AccountManager.getInstance(conn1);
    manager.sensitiveOperationOverInsecureConnection(true);//不加会报错,敏感操作。
    try {
        manager.createAccount(Localpart.from("fuck"),"123");
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Conn1是从服务中获得的连接。

依然报错:

com.xzq.textofim W/System.err: org.jivesoftware.smack.XMPPException$XMPPErrorException: XMPP error reply received from xxxx. XMPPError: bad-request - modify

xxxx是本机IP,我匿了。

诶,卧槽。没毛病啊,不就是这么弄的吗。逻辑上没有问题啊。我查了许久,有说没设置ServiceName的,或者ServiceName不能从localhost(127.0.0.1)上得的。但是都没有解决问题。依然是注册不了,依然是这个报错。

本来我是写在一个有UI里的,但是实在不知道哪错了。

心灰意冷之下,新开工程,把核心连接登录注册的代码直接撸上。用户名密码不再是自己在手机或者模拟器上输入的了(也就是本文给出的代码)。

无意中尝试,终于得到答案。这特么的也太恶心了。

注册居然需要先登录,才能注册。

也就是说,必须在注册之前,先进行登录。这坑爹的逻辑。所以,在注册的Activity中,先进行登录。然后再注册。

成功了。当然还有些问题就是,登录完了以后,必须得退出登录。然后回到登录的Activity中,才能用注册的账号登录。

这之中还有些坑,暂且不表,可以不管,继续后面的内容。

第一次写博客,希望我写的内容能对大家有些帮助!

展开阅读全文

没有更多推荐了,返回首页