合肥程序员群:49313181。    合肥实名程序员群:128131462 (不愿透露姓名和信息者勿加入)
Q  Q:408365330     E-Mail:egojit@qq.com

 综述:

每天利用中午时间更新下这个知识点的的博客如果感兴趣的觉得更新慢了也别介意(其它时间还是以工作为主,学习工作两不误,哈哈……)。上一篇我纯理论上简单讲解了一下XMPP协议,然而现在用的比较多的XMPP协议服务器当然是openfire最为流行(我感觉)。至于如何搭建oprenfire 二次开发环境并且将代码跑起来,这一篇不介绍了,后面下一篇介绍,也许会有点顺序乱的感觉,但是主要还是我最近两天再搞IM整合现有系统用户。所以这一遍是记录篇也是发出来和大家一起分享心得(毕竟网上很多博客是没有经过验证的理论篇),我这里都是经过实际环境并且通过测试的,否则我不会记录。在这里我们需要两份源代码,因为在配置中我们会进行源码调试,一方面我们要读openfire源码,另一方面我们要一个客户端登录XMPP服务器聊天验证,首先上着两份源码在eclipse中的结构(后面会记录如何搭建源码环境并且将源码跑起来)

图1

首先Openfire 的源码使用的是最新的3.10.2版本,客户端Spark 是pc客户端,使用的是最新的2.7.2版本,如上图所示。

首先描述一下业务场景,公司有一个现有的OA系统,是.NET(C#语言)平台下开发的,使用SqlServer数据库。让后给OA加上即时聊天功能,本来是打算维护两份用户数据,后来了解到现有OA的用户是密码是MD5加密,而openfire默认是Blowfish加密,这个时候如果是新建用户还好,但是以前在使用的OA系统中MD5加密的用户怎么办??如果直接导入到IM用户表中肯定是无法使用的,这个时候就需要整合现有用户表,openfire中的用户表废弃,只使用现有系统中的用户表,OA系统和openfire都是通过OA系统用户表登录,所以需要整合。然后就免不了分析openfire源码,才有了下面的文字,根据openfire源码让你知其然知其所以然。否则只知道这样配置,而不知道为什么这样配置,那就不好了,凡事弄明明白白(程序猿精神)。

openfire整合现有系统用户

首先明确我的现有系统是一个SqlServer数据库,IM也是sqlserver(当然混合数据库也是可以的,已经这样做过IM是mysql,就有系统是SqlServer)。

一.配置provider.auth.className

private static void initProvider() {// Convert XML based provider setup to Database basedJiveGlobals.migrateProperty("provider.auth.className");String className = JiveGlobals.getProperty("provider.auth.className","org.jivesoftware.openfire.auth.DefaultAuthProvider");// Check if we need to reset the auth provider class if (authProvider == null || !className.equals(authProvider.getClass().getName())) {try {Class c = ClassUtils.forName(className);authProvider = (AuthProvider)c.newInstance();}catch (Exception e) {Log.error("Error loading auth provider: " + className, e);authProvider = new DefaultAuthProvider();}}}

由openfire源码中AuthFactory类我们知道它的静态函数中调用了这个initProvider()这个静态函数初始化了一些配置,然后通过这个配置构造了一个AuthProvider。这个配置的键为provider.auth.className,默认使用的是org.jivesoftware.openfire.auth.DefaultAuthProvider类,如果我们配置provider.auth.className那么就使用配置的类,然后我们就可以在

openfire源码中找DefaultAuthProvider类 继承自JDBCAuthProvider,继承自AuthProvider类完全符合要求,在数据库中修改ofProperty表相应的值,如下图:

图2

这样用户验证就是通过org.jivesoftware.openfire.auth.JDBCAuthProvider来进行行验证了。我们继续跟踪openfire的java源码,进入JDBCAuthProvider类,它的构造函数代码如下:

图3

由图3很容易知道,我们要配置各种参数如下:

驱动: jdbcProvider.driver

连接字符串:jdbcProvider.connectionString

查询密码的SQL语句:jdbcAuthProvider.passwordSQL

密码的加密类型:jdbcAuthProvider.passwordType

设置密码的SQL语句:jdbcAuthProvider.setPasswordSQL

是否允许修改密码(由后面的源码知道true或者false):allowUpdate

那么我们现在来一个一个跟踪源码讲解整合用户。

1.配置驱动jdbcProvider.driver  这里是SQL server数据库所以用 net.sourceforge.jtds.jdbc.Driver。

2.配置连接字符串jdbcProvider.connectionString  为: jdbc:jtds:sqlserver://192.168.11.21:1433/OA_frame;appName=jive;user=sa;password=mm  替换成你自己的

3.配置查询密码字符串jdbcAuthProvider.passwordSQL 为: select UserPwd from BT_User where UserName=?  这里的 UserName是用户登录名称,UserPwd就是密码字段,BT_User就是用户表。为什么是这样请看下面源代码就懂了:

图5 

4.配置密码加密类型jdbcAuthProvider.passwordType   为md5  ,但是一定要注意要小些字符串"md5"如果问为什么,那是因为openfire源码中不认识"MD5"这种大写。这个支持哪些加密方式呢??很容易有下面的枚举知道:plain不加密,md5,sha1,sha256,sha512这些加密方式

 1  public enum PasswordType {
 2
 3         /**
 4          * The password is stored as plain text.
 5          */
 6         plain,
 7
 8         /**
 9          * The password is stored as a hex-encoded MD5 hash.
10          */
11         md5,
12
13         /**
14          * The password is stored as a hex-encoded SHA-1 hash.
15          */
16         sha1,
17
18         /**
19          * The password is stored as a hex-encoded SHA-256 hash.
20          */
21         sha256,
22
23         /**
24           * The password is stored as a hex-encoded SHA-512 hash.
25           */
26         sha512;
27    }

5. 设置 修改密码SQL脚本jdbcAuthProvider.setPasswordSQL  根据自己的需要设置修改密码脚本,根据源码可以知道它也是把用户登录名作为条件查询修改的,也就是修改制定登录名用 户的密码。

6. 配置是否允许修改密码allowUpdate    如果配置了jdbcAuthProvider.setPasswordSQL 就插入true吧。否则jdbcAuthProvider.setPasswordSQL 配置的就没有用了,看代码为什么

图6

通过图6制定为什么了吧??:)

二.配置provider.user.className

我们配置provider.user.className为 org.jivesoftware.openfire.user.JDBCUserProvider 请看上面图2。这个配置好了,那么我们就要配置相关属性了。看下图代码:

 图7

很容易看出在这里我们要配置哪些属性:

1.jdbcProvider.driver(上面已经配置)

2.jdbcProvider.connectionString(上面已经配置)

3.jdbcUserProvider.loadUserSQL

4.jdbcUserProvider.userCountSQL

5.jdbcUserProvider.allUsersSQL

6.jdbcUserProvider.searchSQL

7.jdbcUserProvider.usernameField

8.jdbcUserProvider.nameField

9.jdbcUserProvider.emailField

1.配置加载用户信息SQL脚本jdbcUserProvider.loadUserSQL  是根据登录名查询用户信息的字符串 select RealName,Email from BT_User where UserName=? 我们再看看源码:

 图8

由上面图8知道,我们查询只需要查询出用户名(不是登录名),邮箱就行了,其它的查询出来也没什么用,而且字段顺序要正确哦(看源码知道用户第一次被加载后就放入了缓存)。

2.配置查询用户数量脚本jdbcUserProvider.userCountSQL 为:select count(*) from  BT_User   这个就没什么好说明的了

3.配置用户登录名字段 jdbcUserProvider.usernameField  我们这里就是UserName了

4.配置用户名jdbcUserProvider.nameField 为:RealName  这里是昵称或者是真实姓名,这个就看你具体业务了因为这个是要展示给用户看到的

5.配置邮箱字段jdbcUserProvider.emailField 为:Email 就是用户邮箱没什么可说的

结束:

上面围绕配置JDBCAuthProvider和JDBCUserProvider 到这里就完成了,重启openfire然后这个时候重新登录用户发现现在所用的用户就是旧有系统中的用户了,用户整合完成(至少也只是用户数据整合完成)。更多的配置:如果你系统中有用户部门什么的,还有如果你希望openfire支持整合后用户有更多操作那么还需要配置其它东西,我就不一个个说明,但是遵循这种源码跟踪思路足够应付各种配置,已经配置中出现的问题。

综合配置点:

一):provider.auth.className

  驱动: jdbcProvider.driver

  连接字符串:jdbcProvider.connectionString

  查询密码的SQL语句:jdbcAuthProvider.passwordSQL

  密码的加密类型:jdbcAuthProvider.passwordType

  设置密码的SQL语句:jdbcAuthProvider.setPasswordSQL

  是否允许修改密码(由后面的源码知道true或者false):allowUpdate

二):provider.auth.className

  jdbcProvider.driver(上面已经配置)

  jdbcProvider.connectionString(上面已经配置)

  jdbcUserProvider.loadUserSQL

  jdbcUserProvider.userCountSQL

  jdbcUserProvider.allUsersSQL

  jdbcUserProvider.searchSQL

  jdbcUserProvider.usernameField

  jdbcUserProvider.nameField

  jdbcUserProvider.emailField

后记:

有兴趣或者有问题的可以加上面的QQ群讨论有什么问题咨询的欢迎打扰。商业合作当然更欢迎

转载于:https://www.cnblogs.com/egojit/p/4900726.html

即时聊天IM之二 openfire 整合现有系统用户相关推荐

  1. java xmpp 框架_即时聊天IM之三 XMPP协议客户端库的和Android端框架概述

    合肥程序员群:49313181.    合肥实名程序员群:128131462 (不愿透露姓名和信息者勿加入) Q  Q:408365330     E-Mail:egojit@qq.com smack ...

  2. 即时聊天工具二次开发

    突然想做一个能够通知另一台电脑消息的工具.因为是自己用,又不想大动干戈,想想不如就采用现有即时聊天软件如QQ.MSN等开发个小程序就行了.我现在也不愿意编程,能少费事就少费事. 研究了QQ的二次开发, ...

  3. Android使用XMPP框架实现即时聊天(IM)功能(Openfire + Smack)

    目录 概述 前期准备 客户端使用Smack 权限配置.压缩包导入等 客户端连接到服务器 用户注册/登录功能 离线消息接收 接收/发送消息 后记 概述 即时聊天功能是许多APP的刚需.QQ.微信等用的都 ...

  4. Vue 使用 Vue-socket.io 实现即时聊天应用(实战篇 二)

    Gitee源码:https://gitee.com/wfeng0/CSDN GitHub源码:GitHub - wf0/CSDN: vue-socket.io实现即时聊天 视频介绍:vue-socke ...

  5. openfire android 发送图片,基于openfire+smack开发Android即时聊天应用[四]-单人聊天、群聊、发送接收文件等...

    这篇文章主要介绍如何实现点对点单人聊天.多人的群聊.以及如何给对方发送文件,如何发送图片消息和语音消息等功能. 1.单人聊天 1.首先创建聊天对象 /** * 创建聊天窗口 * @param jid ...

  6. 即时聊天社交软件(二)

    即时聊天社交软件(二) 这次做一些关于android控件的设置 当用户登陆成功后的界面设置 : 我打算将这个activity设置成有下拉刷新和左菜单栏功能的activity 1. 下拉刷新控件 : 使 ...

  7. 基于openfire+smack开发Android即时聊天应用[三]-账号信息、添加好友、JID理解等

    基于openfire+smack开发Android即时聊天应用[三]-账号信息.添加好友.JID理解等 标签: SmackOpenfireandroid 2015-10-30 18:06  3068人 ...

  8. Android基于环信SDK开发IM即时聊天(二)

    声明1:北京时间现在是2019/6/10,评论里的问题我看到了,这几天我找时间看看源代码问题出在哪,在此感谢大家的监督 声明2:此Demo我是在5.1测试机上测试通过,感谢WTQ_DOMIAN的评论, ...

  9. 即时聊天IM软件集合

    IM,Instant Messenger,即时传讯的缩写.写到这里,大家可能会感到不屑一顾,聊天软件就软件呗,能有什么好说的.但是在实际生活中,就有很多人曾经问过我:什么是MSN?MSN是干吗的?那么 ...

最新文章

  1. python从入门到精通视频-python从入门到精通视频(大全60集)
  2. java远程插件动态注册机制_Spring运行时动态注册bean的方法
  3. 管理软件实施(4)——如何编写售前解决方案
  4. C++11多线程创建的三种方法
  5. linux dd克隆系统后,Ubuntu14.04 dd命令克隆系统镜像安装到另一台机器上
  6. PHP关闭自动过滤,php怎么关闭自动过滤输入和输出
  7. 机器学习笔记(十九):逻辑回归
  8. 《Linux程序设计》第4版 核心笔记
  9. ArcGIS转CAD坐标
  10. 人工智能:python 实现 第十章,NLP 第一天 入门介绍及使用stemming还原词汇
  11. Ordinal Regression with Multiple Output CNN for Age Estimation-(系列一_年龄估计)
  12. mysql启动报错之[ERROR] Found option without preceding group in config file /etc/my.cnf at line
  13. 推荐几个免费的在线文本转语音网站(支持中英文多种语音)
  14. 计算机应用技术投稿流程,计算机技术与发展投稿有何要求?
  15. 机器翻译评价指标之BLEU原理介绍及代码实现
  16. 【研一小白的白话理解】pytorch-CycleGAN-and-pix2pix
  17. QQ空间点赞源码,基于autojs的安卓免root全自动脚本
  18. 小i机器人在2018硬科技年会上夺双料大奖
  19. 大学生如何让自己强大起来(计算机、电子方向)
  20. windows云服务器部署web网站

热门文章

  1. java POI 写入百万数据到 excel
  2. Android学习笔记——Menu(二)
  3. 监控系统的多协议直播(RTSP RTMP HTTP Live Streaming)
  4. 查询DB中每个表占用的空间大小
  5. matplotlib  plt.scatter
  6. workerman php访问,workerman 配置域名访问 (本地)
  7. 新浪微博爬虫设计(Python版)
  8. Java日志操作总结
  9. 参数php_PHP多参数方法的重构
  10. lua检测表中是否有某个值_Lua检测数组(tabble)中是否包含某个值