扩展XMPP客户端的认证机制和消息类型

举报
VR小粉丝 发表于 2020/01/19 14:40:49 2020/01/19
【摘要】 XMPP(Extensible Messaging and Presence Protocol,可扩展消息与存在协议)是目前主流的即时消息传输协议。由于XMPP服务端的认证机制不同,需要XMPP客户端扩展对应的认证机制,否则无法接入XMPP服务器。同样,XMPP服务端的接口会定义一些自定义的消息类型,用于支撑不同业务。这时,需要XMPP客户端同样支持扩展消息类型,否则无法识别消息,出现报错。...

XMPPExtensible Messaging and Presence Protocol,可扩展消息与存在协议)是目前主流的即时消息传输协议。

由于XMPP服务端的认证机制不同,需要XMPP客户端扩展对应的认证机制,否则无法接入XMPP服务器。

同样,XMPP服务端的接口会定义一些自定义的消息类型,用于支撑不同业务。这时,需要XMPP客户端同样支持扩展消息类型,否则无法识别消息,出现报错。

开源软件Smack是一款Java实现的XMPP客户端软件,下面分享如何在Smack的基础上扩展认证机制和扩展消息类型。

1、扩展认证机制

下面,我们以视频平台的XMPP服务端的认证接口定义为例,扩展Smack客户端的认证机制。

XMPP服务端认证接口定义(客户端的认证必须根据XMPP服务器的接口实现)如下:

请求消息定义:

参数名

参数类型

必选(M)/可选(O)

参数说明

auth

元素

M

用于承载授权机制的XMPP节。

auth/xmlns

属性

M

默认为:urn:xmpp:sm:hw_ext

auth/mechanism

属性

M

鉴权算法,默认为:TOKEN

auth/username

元素

M

客户端JID

auth/token

元素

M

客户端token值,采用base64编码。

消息示例:

<auth xmlns='urn:xmpp:sm:hw_ext' mechanism='TOKEN'>

<username>user1@im.huawei.com</username>

<token>YWJjZGVmJSYqNTY3ODk=</token>

</auth>

响应消息定义:

参数名

参数类型

必选(M)/可选(O)

参数说明

success

元素

M

表示鉴权成功。

success/xmlns

属性

M

默认为:urn:xmpp:sm:hw_ext

success/heartbeat

属性

O

表示服务器希望客户端发送ping心跳的时间间隔,单位为秒。

不带本属性时,默认为:300

success/heartbeatTimes

属性

O

心跳检测次数。

不带本属性时,默认为:5

响应示例:

<success xmlns='urn:xmpp:sm:hw_ext ' heartbeat='300'/>

1.1定义认证消息类MyExtAuthMechanism

MyExtAuthMechanism继承SaslStreamElements.AuthMechanism类,重写public String getNamespace()public XmlStringBuilder toXML(String enclosingNamespace)

getNamespace方法返回消息的命名空间,例如上面定义“urn:xmpp:sm:hw_ext”。

toXML方法返回认证的xml消息,例如上面定义的消息示例。

1.2定义认证机制类MyExtSASLMechanism

MyExtSASLMechanism继承SASLMechanism类,重写public void authenticate(String host, DomainBareJid serviceName, CallbackHandler cbh, EntityBareJid authzid, SSLSession sslSession) throws SmackException, NotConnectedException, InterruptedException方法。

authenticate方法会向XMPP服务端发送认证消息,消息包装在MyExtAuthMechanism对象。

代码示例如下:

mechanism = "TOKEN";

authenticationText = "<username>user1@im.huawei.com</username><token>YWJjZGVmJSYqNTY3ODk=</token>"

// connection是父类中的XMPPConnection对象,用于发送消息至XMPP服务器

connection.sendNonza(new MsaAuthMechanism(mechanism, authenticationText));

1.3增加认证响应消息处理

         认证的响应消息中携带了心跳参数,Smack不支持处理认证响应中的参数,需要扩展认证成功消息处理步骤。

         smack-tcp模块的XMPPTCPConnection类中的parsePackets方法,增加对Success.ELEMENT消息的处理。例如提取响应中的心跳间隔时间。

1.4注册自定义认证机制

SASLAuthentication类提供了静态方法public static void registerSASLMechanism(SASLMechanism mechanism)用于注册一个新的认证方式;以MyExtSASLMechanism对象为参数,注册自定义认证机制。

1.5认证过程

         XMPP客户端与服务端建立连接的过程如下:

1579415783821306.png

         认证过程包括10.Select an authentication mechanism11.Send the authentication success response

         Smack软件中,AbstractXMPPConnection类抽象了XMPP连接,XMPPTCPConnectionAbstractXMPPConnection子类,调用XMPPTCPConnectionconnect方法与XMPP服务器建立通道连接,调用login方法进行登录认证。

         login方法最终调用SASLAuthentication类中的authenticate方法,authenticate根据服务端支持的认证类型id选择对应的认证机制,例如上面定义的“TOKEN”,然后调用MyExtSASLMechanismauthenticate方法,将认证请求消息发送至服务端。详情可参考SASLAuthentication类中的authenticate方法。

2、扩展消息类型

         下面,我们以支持视频平台的XMPP服务器的系统控制消息为例,扩展Smack客户端消息类型。

         系统控制消息用于表示系统控制相关的命令,例如restart(重启)。

         消息定义如下:

参数名

参数类型

必选(M)/可选(O)

参数说明

message

元素

M

用于承载即时消息的XMPP节。

message/type

属性

O

消息类型,普通文本消息为:chat,控制消息为:sys-ctrl

message/id

属性

M

该即时消息的ID,由客户端自行生成。

message/from

属性

O

消息发送方Full JID

message/to

属性

M

消息接收方Bare JID/Full JID

message/body

元素

M

UTF-8编码的消息内容。

message/request

元素

O

要求的报告类型,通过type属性携带。

message/request/xmlns

属性

M

固定取值为:urn:xmpp:receipts

message/request/type

属性

O

发送方要求的报告的类型。

控制消息示例:

<message type='sys-ctrl' id='purplea7adefbc' from='111@im.huawei.com/pushclient' to='222@im.huawei.com'>

<body>restart</body>

<request xmlns='urn:xmpp:receipts'/>

</message>

消息类型定义在Smack core模块Message类中的Type内部类中,无法通过调用接口的方式扩展,只能通过修改Type类,增加新的消息类型。

         例如在Type类中增加一个控制消息类型:

public enum Type {

    // Default) a normal text message used in email like interface.

    normal,

    // pically short text message used in line-by-line chat interfaces.

    chat,

    // at message sent to a groupchat server for group chats.

    groupchat,

    // xt message to be displayed in scrolling marquee displays.

    headline,

    // ysctrl message sent to destination client for execute system command.

    sysctrl,

    // dicates a messaging error.

error;

}

需要注意的是,由于历史原因,上面XMPP消息类型sys-ctrl的定义中包含”-” 号,而Java变量中是不能包含”-” 号,因此上面定义的Type枚举值为sysctrl

在解析、生成sys-ctrl消息时,需要对变量做sysctrl < -- > sys-ctrl转换,否则枚举值解析会报错。

同样,在定义接口中的消息类型时,也要考虑代码的实现。

2.1解析系统控制消息

XMPP客户端收到服务端的消息时,会执行XMPPTCPConnection类中的parsePackets方法,根据消息的元素判断,如果是Message.ELEMENT消息,则调用parseAndProcessStanza方法解析消息内容。

         parseAndProcessStanza方法最终会调用PacketParserUtils.parseMessage方法,parseMessage方法中根据Message.Type的枚举值解析消息类型,如果消息类型在Type中未定义,则出现消息解析失败错误。

public static Message parseMessage(XmlPullParser parser) hrows Exception {

    ……

    if (typeString != null) {

        // 根据Message Type枚举值来解析消息类型

        message.setType(Message.Type.fromString(typeString));

}

3XMPP应用场景

         通过XMPP,可以实现VR头盔和大屏的同屏。

         DLNA不同,XMPP不受局域网限制,只要客户端与服务端网络连通,即可实现即时消息;

1579415844928562.png

         360视频的同屏场景下,通过XMPPVR头盔可以即时传送当前的角度至同屏机顶盒,机顶盒根据角度拉取符合大屏显示的分辨率的视频流,可以解决VR头盔视频分辨率与大屏分辨率不一致的问题。

 

 



推荐

华为开发者空间发布

让每位开发者拥有一台云主机

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。