基于Hemlock的ejabberd ActionScript游戏客户端开发

时间:2021-11-21 18:53:20

1 基本概念

1.1 Widget和Container

参见http://hemlock-kills.com/learn最后一节,HemlockContainer的子类是一个Sprite,是hemlock最*的组件。本来它应该是Hemlock框架下的应用程序最*Sprite,在我们的应用里做不到也至少应该保证它的唯一性,因为它维护着跟ejabberd服务器的连接和用户在线等信息。需要用到聊天与状态信息的功能模块最好都写成一个个的Widget,然后调用addWidgets放到HemlockContainer里去
它提供一个叫client的getter,可以获得XMPPClient的实例,这个后面经常要用到。

1.2 事件与全局的dispatcher

很多事件的监听都是加在这个上面,单例,HemlockWidget和HemlockContainer都有get dispatcher()。
HemlockWidget和HemlockContainer共同的父类HemlockSprite提供了一个registerListener(widget.dispatcher,  EVENT_TYPE,onSomeEvent);方法,用于注册监听器。注册完之后需要手动调用startListeners();

1.3 聊天室(Multi-User Chat, MUC)

XMPP协议支持的聊天室比QQ群强大一些,QQ群只有成员的概念,只有成员才能在群里说话,某人一上线就同时在他所在的所有群里出现了。XMPP协议则支持两个维度来描述一个人与一个聊天室之间的关系,也就是角色与会员(roles andaffiliations,参见http://xmpp.org/extensions/xep-0045.html#connections)。会员描述了某个人与某个群长期的一种状态,这点跟QQ群有点像:某人一旦加到某个群(聊天室)后,不管他在不在线,他都是那个群的成员(member),高级的成员可以踢人,群拥有者可以解散群等等。相反,角色描述了某个人与某个群临时的一种状态,他可以登录,同时也是某个群的成员,但不参与到某个群的讨论,于是别人也看不见他,此时他的role是该群的member,但affiliation却不是该群的participant,于是就无法向那个群里发消息。要发消息前必须先向服务器请求进入某个群天室。
我们可以为每个用户建立好一个聊天室,别人来访相当于加到这个聊天室。在同一个房间里的所有参与者都需要知道的信息都可以用聊天室的群聊功能来实现。顺便提一下,我们目前只需要在有限的房间里交互,用XMPP就可以实现,如果想在一个大地图上的任意一个地方交互,估计就得用Darkstar了

1.4 Hemlock中的消息与控制数据

//底层传输是不区分这两种数据的,但是上层在做事件监听对于两种数据却需要分开处理。区别方法是消息的id是以JID.TYPE_CHAT+"__"开头的,而控制消息则是以JID.TYPE_APP+"__"开头

2 建立聊天室

 

2.1. 向服务器请求建立

container.createChatRoom-->dispatcher发出AppEvent.CONFIGURATION_START事件
container.createChatRoom可传入JID.TYPE_APP或JID.TYPE_CHAT,用于区别是建立聊天室还是游戏的某个房间

2.2 配置聊天室信息(可选)与加入聊天室

处理AppEvent.CONFIGURATION_START事件然后调用下面方法配置聊天室,
container.configureChatRoom(_toJID, _configOptions);-->dispatcher发出AppEvent.CONFIGURATION_COMPLETE
其中_toJID==AppEvent.CONFIGURATION_START事件的event.from参数
_configOptions是聊天室的参数,以Object类型存在,可以配置的参数如下:


 
配置完成后会XMPPClient会自动加入聊天室(XMPPClient::handleCustomConfigResponse)-->AppEvent.ROOM_JOINED和AppEvent.PRESENCE_UPDATE(在XMPPClient::onPresenceUpdate)

3 加入聊天室

container.joinChatRoom(room JID);-->dispatcher发出AppEvent.ROOM_JOINED和AppEvent.PRESENCE_UPDATE(在XMPPClient::onPresenceUpdate)

AppEvent.ROOM_JOINED的处理可以显示该聊天室信息等

AppEvent.PRESENCE_UPDATE可以显示聊天室当前的人,可参见hemlock/src/com/mintdigital/hemlock/widgets/chatroom/ChatroomWidgetEvents.as中onPresence的实例

4 退出聊天室

container.leaveChatRoom(room JID);-->dispatcher发出AppEvent.ROOM_LEAVE和AppEvent.PRESENCE_UPDATE(在XMPPClient::onPresenceUpdate)

与加入类似

 

 

 

5 群发消息

 

消息有两种类型,一种是真实的聊天消息,另一种是以消息形式发送的控制数据。

聊天消息:

控制消息: 其中DrawEvent.BRUSH可替换为应用自定义的其它消息类型。由于一个widget实例维护着一个聊天室的信息,这里不需要再指定聊天室ID

 

6 接收消息

6.1 实现IEventStrategy,过滤对应类型的消息

消息的ID都是以 这种形式存在的,可以定义某个常量的值为"某类型"这个字符串,然后在IEventStrategy子类里判断如果消息类型以"某类型"开头,就发出对应用户自定义事件来通知对应处理代码

例子:hemlock/src/com/mintdigital/hemlock/strategies下的各个类

6.2 把Strategy类加到XMPPClient 实例中去

例子 

 

6.3 监听对应消息并进行处理

完成上一步后,当一个消息到达,对应的Strategy就会发出相应的消息,通知应用改变状态,比如收到一个群聊消息或者房间里的某个人交换了某件物品,都可以用这种方式处理