xmppmini 项目详解:一步一步从原理跟我学实用 xmpp 技术开发 2.登录的实现
第二章登录的实现
金庸《倚天屠龙记》
张三丰缓缓摇头,说道:“少林派累积千年,方得达成这等绝技,决非一蹴而至,就算是绝顶聪明之人,也无法自创。”他顿了一顿,又道:“我当年在少林寺中住过,只是未蒙传授武功,直到此时,也不明白寻常血肉之躯如何能练到这般指力。”
前言
大家肯定不知道,要说其实 xmpp 里最关键、开发中也最不好解决的其实是登录过程你信么?
我要说我只用两句话就能完成 xmpp 登录你信么?
2.1 登录的原理
前面的第一章写得稍显啰嗦,下面我们来实现具体的功能。首先要实现的就是我们这一节要说的登录功能。
说来大家也许不相信,其实 xmpp 实现中最难的部分其实就是第一步:登录。过了这一关之后,其实后面的部分几乎没有什么难度可言,就是些正常的客户机/服务器应答而已。
登录部分难就难在其协议的复杂性和兼容性上。和电子邮件一样,其实登录过程是有多种实现可选择的,不过这实际上并没有什么必要全部实现(对于个人开发者来说也不太可能有精力全部实现),就象电子邮件客户端一样,我们实现其中一种最常见的就可以了,我们在文章中会解释为何选择这种登录方式。
xmpp 和我们前面介绍的 smtp/pop3 一样是以字符串应答为基础的,所以也可以将其交互过程以对话的形式进行描述(当然会有不一样的地方,用到时我们会提到)。具体的与服务器的对话方法我们在《一步一步从原理跟我学邮件收取及发送》中已经介绍过了,不清楚的同学可以移步过去先学习一下,这里我们就不赘述了。
2.2 建立测试环境
和电子邮件一样,要测试我们的程序和想法需要有一台可用的服务器,大家可以直接注册我们的 newbt.net 免费邮箱,会自带 xmpp 功能。xmpp 的完整功能需要您升级为 1 元包年用户,不过我们目前提到的功能在免费用户级别就可以完成了(其实我们的 newbt 免费邮箱和 xmppmini 项目大体上是个众筹项目,大家觉得有用就支持吧,不会强制收费)。希望自己掌握服务器的同学也可以使用 openfire 服务器搭建,理论上也可以使用 ejabberd ,不过在开发中笔者发现 ejabberd 的兼容性要比 openfire 差很多,所以推荐 openfire 。不过对于将来想自己开发服务器的同学不推荐你们在 openfire 上二次开发,原因我们后面会讲到(文中如有提到ejabberd 则为ejabberd-19.08-windows)。
我们 xmppmini 项目的账号直接在 http://www.newbt.net:8888 上注册即可(但愿您看到这篇文章的时候我们项目还健在)。Openfire 需要在http://www.igniterealtime.org/projects/openfire/index.jsp 下载,笔者测试的版本是openfire-4.1.4-1 因为igniterealtime 家的向前兼容性并不怎么好,所以不能保证与最新版本的 openfire 兼容。Openfire 似乎不支持多域名,所以在安装时如果是在局域网中测试,一定要先固定自己的 ip 否则下次开机后就可能无法连接了。
2.3 登录协议与必须要注意的坑
如前所述我们只介绍其中一种最常用的登录协议,原因为其他的登录方式我们得说上一周而且并不怎么实用。综合考虑推荐大家都使用这种登录方式。在 xmpp 协议中,这种登录方式称之为“PLAIN”。
通常 xmpp 连接的是服务器的 5222 端口,双方对话过程如下:
1. 客户端首先发送信息。
类似于:
<?xml version="1.0"?>
<stream:stream xmlns:stream="http://etherx.jabber.org/streams" version="1.0" xmlns="jabber:client" to="newbt.net" xml:lang="en" xmlns:xml="http://www.w3.org/XML/1998/namespace">
服务器的回复类似于:
<?xml version='1.0'?>
<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' from='xumatomacbook-pro.local' id='675c6847-c13d-4710-9844-d9339e4df087' version='1.0' xml:lang='en'>
就是这么简单的第一句对话,其中也有很容易出错的兼容性问题。
对于 openfire 和 newbt.net 服务器,to 的部分可以随便写。对于 ejabberd-19.08-windows 则一定要写上正确的对应域名(局域网测试的话则是 IP)
否则会报
<stream:error> <host-unknown xmlns='urn:ietf:params:xml:ns:xmpp-streams'/> </stream:error> </stream:stream>
另外,现在 ejabberd 的版本似乎一定要 ssl 连接
可修改 C:/ProgramData/ejabberd/conf/ejabberd.yml 中的 starttls_required 为 false 否则没法用明文对话进行测试。
可以看到 xmpp 中收发的字符串并不是标准的完整 xml 格式,其实严格来说它只是 xml 格式的节点片段。其中的<?xml version='1.0'?> 并不是必须的。了解这些在解码 xmpp 的信息时是非常重要的。
2.服务器回应,并且告知自己的可用登录方式。
这第一句话的事情还没完,实际上真实的服务器并不会只回应一条语句,而是会再发送一条语句说明自己支持的功能。类似于:
<stream:features><mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><mechanism>PLAIN</mechanism></mechanisms></stream:features>
所以客户端发送第一条命令后要有准备,自己要接收两条回应信息,如果加上 xml 的信息头就有可能是要接收三条回应,这和 smtp/pop3/ftp 这样的传统网络协议是不同的。
3. 客户端选择最简单的 plaint 方式发送相应的用户名和密码。
类似于:
<auth mechanism="PLAIN" xmlns="urn:ietf:params:xml:ns:xmpp-sasl">AGNjY0BuZXdidC5uZXQAYWFhYWFh</auth>
这里有个问题。就是现在对网络拦截非常重视,理论上有可能会被拦截偷窥到密码。解决的办法 xmpp 给出了很多,不用那么麻烦,我们选择最简单的,直接连接 5223 端口就可以了,除了使用的是 ssl/tls 的通讯方式外其他的不用作任何更改。
发送的消息格式中,红色以外的部分是固定的,而红色部分是一个 base64 后的字符串,它的原文为:”\0用户名\0密码” 伪码如下:
Base64Encode("" + '\0' + user + '\0' + pass)
这里有个超级大坑,在标准协议中这里其实应该是 “登录id+字符0+用户名+字符0+密码”,遗憾的是对这部分协议的理解各家有各家的看法(这种理解上的歧义在 smtp/pop3 中也是非常常见的,也是造成网络协议实现间不兼容的主要原因之一)。目前兼容比较好的方式是将“登录id”直接设置为空字符串,另外在“用户名”这里实际上要带上它的域名,即“用户名+@+host”,例如“clq@newbt.net”而不是直接写上 “clq”。关于这个问题我仔细对比过很多篇同行们的文章教程(rfc文档更不用说了),大多数作者都没有解释这部分内容,但最后他们的给出的代码中格式大多都是采用留空登录 id 的方式。也欢迎大家回复探讨这一问题,特别是对 ejabberd 比较熟悉的用户。目前的现状是如果写了登录 id 的话很可能是过不了 ejabberd 的登录校验的。
4.服务器回应是否成功
类似于:
<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl"/>
如果登录失败的话则类似于:
<failure xmlns="urn:ietf:params:xml:ns:xmpp-sasl"><not-authorized></not-authorized></failure>
5.客户端接收响应,解析出是否成功。
客户端只要判断回应的消息中包含的是success 还是failure 就可以了,连 xml 解码都用不着。
所以综上所述,其实最简单的 xmpp 登录其实客户端只要发送两句话就可以了,而且换用安全套接字后就可以成为实用的登录方式。
这其中的技术难点其实只有一个,那就是服务器回应消息的解码,在下一章节中我们会介绍不使用第三方库的简单又实用的方式。
----------------------------------------------------------------
从本文中大家可以看出,本系列文章假定大家已经看过《一步一步从原理跟我学邮件收取及发送》系列文章,对于一些通用的操作一笔带过了(象base64的编码过程、如何用telnet等工具发送网络命令行、ssl/tls这些)。也节省了不少篇幅。不过这对于初学者有些不太公平,只有建议这部分读者先去认真的跟着《一步一步从原理跟我学邮件收取及发送》文章自己动动手先熟悉下网络程序的常用操作。
xmppmini 项目详解:一步一步从原理跟我学实用 xmpp 技术开发 2.登录的实现的更多相关文章
- Mac下Intellij IDea发布Web项目详解一
Mac下Intellij IDea发布Web项目详解一 Mac下Intellij IDea发布Java Web项目(适合第一次配置Tomcat的家伙们)详解二 Mac下Intellij IDea发布J ...
- eclipse里面构建maven项目详解(转载)
本文来源于:http://my.oschina.net/u/1540325/blog/548530 eclipse里面构建maven项目详解 1 环境安装及分配 Maven是基于项目对象模 ...
- Redis 配置文件 redis.conf 项目详解
Redis.conf 配置文件详解 # [Redis](http://yijiebuyi.com/category/redis.html) 配置文件 # 当配置中需要配置内存大小时,可以使用 1k, ...
- Mac下Intellij IDea发布Java Web项目详解五 开始测试
测试前准备工作目录 Mac下Intellij IDea发布Web项目详解一 Mac下Intellij IDea发布Java Web项目(适合第一次配置Tomcat的家伙们)详解二 Mac下Intell ...
- JAVA Eclipse使用Maven构建web项目详解(SSM框架)
tips: 启动项目后,welcome-file的链接即为测试用例 部署maven web项目 Eclipse使用Maven构建web项目详解 pom.xml添加webapp依赖: <depen ...
- 利用Intellij+MAVEN搭建Spring+Mybatis+MySql+SpringMVC项目详解
http://blog.csdn.net/noaman_wgs/article/details/53893948 利用Intellij+MAVEN搭建Spring+Mybatis+MySql+Spri ...
- [转帖](整理)GNU Hurd项目详解
(整理)GNU Hurd项目详解 http://www.ha97.com/3188.html 发表于: 开源世界 | 作者: 博客教主 标签: GNU,Hurd,详解,项目 Hurd原本是要成为GNU ...
- tomcat通过tomcat 安装根目录下的conf-Catalina-localhost目录发布项目详解
tomcat通过conf-Catalina-localhost目录发布项目详解 Tomcat发布项目的方式大致有三种,但小菜认为通过在tomcat的conf/Catalina/localhost目 ...
- RocketMQ详解(三)启动运行原理
专题目录 RocketMQ详解(一)原理概览 RocketMQ详解(二)安装使用详解 RocketMQ详解(三)启动运行原理 RocketMQ详解(四)核心设计原理 RocketMQ详解(五)总结提高 ...
随机推荐
- Java.数据结构.集合体系详解
I. 第一部分:常见数据结构 首先简单说下数据结构. 什么是数据结构?数据结构就是组织数据的方式. 常见的数据结构:栈,堆,树,图,数组,队列,链表. 这里主要介绍与java集合体系相关的栈.数组和链 ...
- GStreamer基础教程13 - 调试Pipeline
摘要 在很多情况下,我们需要对GStreamer创建的Pipeline进行调试,来了解其运行机制以解决所遇到的问题.为此,GStreamer提供了相应的调试机制,方便我们快速定位问题. 查看调试日志 ...
- 力扣337——打家劫舍 III
这一篇也是基于"打家劫舍"的扩展,需要针对特殊情况特殊考虑,当然其本质还是动态规划,优化时需要考虑数据结构. 原题 在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可行窃 ...
- JSONArray 与 List 互转
List 转 JSONArray // 通过JSONPath获取其中数据,也可以说自己生成的List List<JSONObject> caseList = JsonPath.read(r ...
- PairProgramming 个人第三次作业
Github地址:主仓库 https://github.com/Yanyixiao/PairProgramming.git Partner博客园地址: https://www.cnblogs.com/ ...
- beta版本发布说明与总结
1.发布说明: 软件介绍: deta版本的发布最终是一个可安装使用的窗体程序,已经由Alpha版本的应用解决方案完成到一个程序: deta版本解决了Alpha版本遗留的软件技术方面错误问题,以及针对有 ...
- 异想家Win10系统安装的软件与配置
1.C盘推荐一个硬盘,256G,安装好驱动,显卡配置好高性能,激活Win10,屏蔽WIn10驱动更新(Show or hide updates.diagcab),改电脑名称为Sandeepin-PC. ...
- OpenResty学习指南(一)
我的博客: https://www.luozhiyun.com/archives/217 想要学好 OpenResty,你必须理解下面 8 个重点: 同步非阻塞的编程模式: 不同阶段的作用: LuaJ ...
- jdk8中CompletableFuture的各个API用法,极大扩展了Future
就不介绍了,直接贴代码,建议在代码中使用,真的很方便 package cn.hou.completablefuture; import org.junit.Test; import java.util ...
- java设计模式2————工厂模式
1.工厂模式介绍: 1.1.实现了创建者与调用者的分离 1.2.详细分类: 简单工厂模式 工厂方法模式 抽象工厂模式 1.3.所遵循的OOP原则: 开闭原则:对扩展开放,对修改关闭 依赖倒转原则:面向 ...