Lotus Sametime开发入门.docx
《Lotus Sametime开发入门.docx》由会员分享,可在线阅读,更多相关《Lotus Sametime开发入门.docx(25页珍藏版)》请在冰点文库上搜索。
LotusSametime开发入门
通常来讲,一个好的平台产品除了自身的强大功能外,还应该是开放的,使得开发人员能够进行二次开发和定制,从而扩展平台的功能。
LotusSametime作为IBM市场领先的,企业级实时协作的平台,就符合这两个特征:
自身具备强大的InstantMessaging和WebConferencing能力,同时还开放了一系列API给开发人员使用。
这些API被组织成多个toolkit开放出来。
从开发人员的角度看,这些toolkit可分为客户端和服务器端。
客户端提供与Sametime服务器进行交互的能力,利用它提供的服务和组件,开发人员可以很轻松的把Sametime的相关功能嵌入到自己的应用程序中,比如在线聊天、会议、视频等,甚至开发自己的即时通讯软件。
服务器端toolkit则提供对Sametime服务器进行扩展的API。
开发人员可以把自己的应用程序以类似于插件的方式插入Sametime服务器。
例如简单的"机器人"程序,向用户提供实时的股票,天气等信息;"离线消息"程序,能够向离线用户发送消息,复杂的应用例如拍卖程序,在线游戏等等。
本篇文章作为LotusSametimetoolkit开发入门系列的第一篇,将重点介绍客户端javatoolkit的使用方法,并带领读者循序渐进的开发出两个简单的Sametimejava客户端程序。
LotusSametime是IBM市场领先的、企业级实时协作的平台。
它具备强大的实时通信,在线会议的功能,全世界每天都有超过1500万人在使用Sametime及相关软件。
LotusSametime一个典型的C/S应用。
各个客户端都需要登录到服务器并通过服务器发送各种消息。
Sametimetoolkit可以从IBMdeveloperWorksLotusToolkits页面上下载.该页面上包括从版本3.1,6.5.1到7.0的所有服务器端和客户端的toolkit下载链接。
下表列出了客户端toolkit的不同版本:
版本
用途和使用环境
SametimeJavatoolkit
Toolkit的java版本,提供了全面的服务和组件来方便开发人员进行java应用程序的开发,支持JDK1.1及其以上版本
SametimeC++toolkit
Toolkit的C++版本,定位于Windows平台,可以被用来开发基于Win32和MFC的Sametime应用程序。
SametimeCOMtoolkit
该版本提供了Sametime的一些基本功能,以COM接口的方式发布,可在支持COM,OLE的环境中应用
SametimeLinkstoolkit
该版本用于Web应用程序,通过HTML/JavaScript使得Web页面获得Sametime的相关功能。
注:
本文以Javatoolkit为例来介绍其使用方法,下文中如果没有特殊说明,当提到toolkit时,均是指Javatoolkit。
"分层"在软件系统中是个非常有效的解决问题的方法,Sametimejavatoolkit也划分为3个层次:
UILayer,ServerLayer,TransportLayer。
他们之间的关系如下图所示:
1.传输层(TransportLayer):
位于体系结构的最底层,负责处理和Sametime服务器的通信。
开发人员不必关心这一层。
2.服务层(ServiceLayer):
如下图所示,这一层提供了两大类服务:
Community类服务和Meeting类服务,每一类服务都包含了多个具体的服务(Service)。
本文将着重介绍这些服务的使用方法。
Community类服务中的较常用服务包括:
∙Community服务:
这是最核心,最基本的一个服务,用户通过该服务来登录Sametime服务器。
∙BuddyList服务:
该服务使得开发人员能轻松的读取/设置一个用户的"联系人列表",而不需要处理复杂的底层协议。
∙InstantMessage服务:
主要用来发送/接受各种实时的消息,消息可以是文本或二进制数据。
∙Places服务:
该服务允许用户创建虚拟的空间(Place),并且可以在其中进行协作。
Meeting类服务中常用服务有:
∙ApplicationSharing服务:
在虚拟的Place中,多个用户可以共享一个应用程序,该服务提供了一些UI组件来显示应用程序。
∙WhiteBoard服务:
通过该服务和相关的UI组件,开发人员能够创建虚拟的白板,用户可以画线、方框、圆等基本图形。
3.UI层:
位于toolkit体系的最上层,它提供了多种UI组件方便程序员开发,例如:
只需要简单的调用ChatUI的几个方法,就能提供一个简单的聊天界面。
使用UI层的API可以极大的简化程序员的开发工作。
限于篇幅,本文不可能涉及的介绍客户端toolkit中的所有服务。
本文将随着介绍客户端toolkit中的最重要服务带领读者完成一个简单的登录聊天的应用程序(STClient)。
有兴趣的读者可以自行阅读本文列举的参考资料和客户端toolkit自带的其他示例程序。
开发完成后,读者可以通过此示例程序完成如下功能:
∙登录到Sametime服务器
∙查找用户
∙与指定用户一对一聊天
∙多用户共享桌面
该程序界面如下图所示:
为了便于读者理解,本文中的代码只是从程序中摘取的一些片断并做了少许修改,完整的代码可以在参考资料中下载。
Community类服务
1.Community服务(CommunityService):
登录Sametime服务器
STClient程序要做的第一步就是登录到Sametime服务器,这就需要使用toolkit中最基本的一个服务CommunityService,通过它才能登录到Sametime服务器。
另外该服务还可以接收管理员消息,改变用户状态和隐私设置。
使用该服务登录到Sametime需要下面几个步骤
步骤一:
创建Session对象
session=newSTSession("STClientSession"+this);
session.loadSemanticComponents();
session.start();
上面的代码片断首先创建一个STSession对象,通过它才能装入Sametime的所有服务,在本例中根据我们的需求使用了loadSemanticComponents()方法,toolkit也提供了其他方法来装载特定的服务,请参考相关文档。
在STSession使用之前,我们必须调用它的start()方法。
步骤二:
,获得Community服务对象并登录
我们需要通过session对象获得CommunityService的引用并使用loginByPassword()方法登录。
注意所有的Sametime的组件都有COMP_NAME属性。
comm=(CommunityService)session.getCompApi(CommunityService.COMP_NAME);
comm.loginByPassword(host,user,pwd);
loginByPassword的三个参数分别是sametimeserver地址,用户名和密码
步骤三:
实现LoginListener
因为Sametime是在网络上运行的程序,所以登录过程可能需要一定时间。
我们不希望程序一直等待登录成功的确认,所以我们需要实现Listener接口让Community服务在登录成功后通知程序。
因此我们需要为Community服务对象绑定LoginListener并实现LoginListener接口的两个方法:
loggedIn()和loggedOut()。
首先在调用loginByPassword()方法前增加语句
comm.addLoginListener(newLoginHandler());
然后在LoginHandler类中实现LoginListener接口。
publicclassLoginHandlerimplementsLoginListener{
publicvoidloggedIn(LoginEventevent){
System.out.println("Loginsuccessful");
}
publicvoidloggedOut(LoginEventevent){
System.out.println("Logoutsuccessful");
}
}
步骤四:
注销
最后,不要忘记,在程序关闭时,必须要关闭并注销所有Sametime对象。
publicvoidwindowClosing(WindowEvente){
comm.logout();
session.stop();
session.unloadSession();
}
通过以上这四步,我们可以看到Sametime中基本的设计模式:
观察者模式(Observerpattern)。
在客户端向服务器发出请求之前(比如Login),先创建一个观察者(如LoginListner的实现类),把它加入到适当的组件中去。
这样请求完成以后,观察者的相关方法会被调用(如loggedIn()方法),对结果(比如登录是否成功)进行处理。
观察者模式在对Sametime的编程中几乎无处不在,下文中会有更多的示例。
本小节详细的代码参见示例程序STClient类。
2.Lookup服务(LookupService):
查找用户
登录到系统以后,在向任何一个用户发送消息之前,我们先要获得这个用户的引用。
在Sametimetoolkit中,用户(User)模型非常重要。
简单的来讲,该模型包括静态的User和动态的User,静态User代表Sametimecommunity中的一个实体,在toolkit中与之对应的是STUser类。
一旦用户登录到系统中以后,就产生了一个动态的User,可用STUserInstance来表示。
如果一个用户登录多次,就会产生多个不同的STUserInstance对象。
在这里我们只需要获得STUser对象的引用。
步骤一:
获得LookupService对象
同获得CommunityService对象相似,我们通过调用STSession的getCompApi方法,传入LookupService的COMP_NAME属性,并通过强制类型转换获得LookupService的引用。
LookupServicelookup=(LookupService)session.getCompApi(LookupService.COMP_NAME)
步骤二:
解析用户
解析用户需要使用Resolver类。
我们首先用LookupService对象创建Resolver类,然后使用该类的resolve()方法解析指定用户。
Resolverresolver=lookup.createResolver(false,//返回所有匹配
false,//非穷尽搜索
true,//返回搜索到的用户
false);//不返回搜索到的组
resolver.resolve(userNames);
步骤三:
实现ResolveListener
同样,由于在网络上解析用户需要一定时间,我们使用观察者模式接收解析结果消息。
这里需要实现ResolveListener接口和它的三个方法。
首先在调用resolve()方法前增加语句:
resolver.addResolveListener(newResolveHandler());
然后在ResolveHandler中实现ResolveListener接口。
如果解析成功,resolved()方法将会被调用。
在本例中,如果解析失败或解析到多个用户,我们不作任何处理。
publicclassResolveHandlerResolveListener{
privateSTUserstUser=null;
publicvoidresolved(ResolveEventevent){
stUser=event.getResolved();
}
publicvoidresolveConflict(ResolveEventevent){
}
publicvoidresolveFailed(ResolveEventevent){
}
}
本小节详细的代码参见示例程序AddUserDialog类。
3.InstantMessaging服务(InstantMessagingService):
进行实时交谈
现在我们已经可以获得一个用户的实例,接下来希望向一个指定用户发送/接收即时消息(InstantMessage),这就需要使用InstantMessaging服务。
用法是先创建一个IM对象,该对象代表了两个Client之间的一次会话,然后通过IM对象能够发送和接收消息。
需要注意的是IM必须被打开以后才能使用。
步骤一:
获得InstantMessagingService对象
首先像创建其他服务对象一样,通过STSession对象获得InstantMessagingService对象。
InstantMessagingServiceimService=(InstantMessagingService)session.getCompApi(
InstantMessagingService.COMP_NAME);
步骤二:
打开即时消息(IM)
打开即时消息需要使用Im类。
我们首先用InstantMessagingService对象创建Im类,然后使用该类的open方法打开即时消息。
Imim=imService.createIm(
stUser,
EncLevel.ENC_LEVEL_NONE,
ImTypes.IM_TYPE_CHAT);
im.open();
步骤三:
实现Listener
在createIm()方法中,参数stUser表示和指定的用户创建一个IM会话,encLevel表示加密级,imType表示IM的类型,常用的是ImTypes.IM_TYPE_CHAT。
同样,我们使用观察者模式接收消息。
这里需要实现两个Listener接口。
∙ImServiceListener:
本接口需要和InstantMessagingService对象绑定,负责接收IM服务的事件,如其他用户向自己初次发送的IM消息。
需要实现的方法有imReceived()。
∙ImListener:
本接口需要和Im对象绑定,负责接收某一个特定IM服务的事件。
即在一个IM创建成功后,本接口只负责接收该IM上的事件。
需要实现的方法有dataReceived(),textReceived(),imOpened(),imClosed(),openImFailed()。
首先在调用open()方法前增加语句:
imService.addImServiceListener(newImServiceHandler());
//该Service只接收Chat类型的消息
imService.registerImType(ImTypes.IM_TYPE_CHAT)
im.addImListener(newImHandler());
然后分别实现这两个Listener接口。
ImServiceListener的实现如下:
publicclassImServiceHandlerimplementsImServiceListener{
publicvoidimReceived(ImEvente){
Imim=e.getIm();
partner=im.getPartner();
im.addImListener(newImHandler());
}
}
假设用户A希望向用户B发送消息,他创建了一个Im对象,添加了ImHandler,然后调用open()方法打开了它,那么在用户B处imReceived()方法就会被触发,用户B在接收到一个用户A创建的IM后,也需要为这个IM添加一个ImHandler对象,以便进行消息的处理
ImListener的实现如下:
publicclassImHandlerimplementsImListener{
publicvoidopenImFailed(ImEvente){
System.out.println("ImOpenefailed,reason:
"+e.getReason());
}
publicvoidimOpened(ImEvente){
System.out.println("ImOpened,sendtext..");
//发送消息,false表示该消息不用加密
e.getIm().sendText(false,"Thisisatest");
}
publicvoidimClosed(ImEvente){
System.out.println("Imclosed");
}
publicvoidtextReceived(ImEvente){
System.out.println("Messagereceived:
"+e.getText());
}
publicvoiddataReceived(ImEvente){
//接收到对方发送的二进制数据
System.out.println("Datareceived:
"+e.getData());
}
}
可以看出,ImHandler能够对多个事件进行响应,常用到的两个方法是:
1.imOpened():
它表示IM已经打开成功,可以发送/接收消息了,在我们的例子中立刻调用了IM的sendText方法发送了一个简单的消息。
2.textReceived():
它利用ImEvent参数能够取得对方发送过来的消息。
本小节详细的代码参见示例程序ChatFrame类。
4.Places服务(PlacesService):
在虚拟空间中进行协作
Place在Sametimetoolkit中是非常重要的结构,它作为一个虚拟的空间,多个用户可以在其中进行协作,在应用程序中使用一个字符串名称和类型来标志Place。
Place中包括三类成员:
User,Section和Activity。
∙User:
代表了进入到Place中的一个用户
∙Section:
一个Place包含多个Sections,可以认为是Place中的"Place"。
其中第一个Section比较特殊,叫做"Stage",它有些特殊的权限,比如可以向整个Place发送消息。
一旦用户进入到Place,就自动了进入了Stage。
当然用户可以也转移到其他Section去。
∙Activity:
表示多个用户在一起进行协作的活动,例如应用程序共享。
多个在线用户之间可以共享、操作某一个用户机器上正在运行的程序。
关于Place的另一个基本概念是PlaceMember。
User,Section,Activity甚至Place本身都是PlaceMember,下面是它们之间的关系图。
图5:
Sametimeplace模型
PlaceMember定义的接口允许成员之间通过发送消息/数据的方式进行通信。
但是对不同的PlaceMember调用sendText()方法,接收者的范围(Scope)有所不同。
例如place.sendText()会导致Place中的所有成员都会接收到消息,而section.sendText()则把范围限定到一个特定Section中。
在我们的例子STClient中,Place会作为一个桌面共享的空间,这一小节只介绍如何进入Place,其他操作在读者能在ApplicationShare服务一节中看到。
步骤一:
获得PlaceService
首先像创建其他服务对象一样,通过STSession对象获得PlacesService对象。
placeService=(PlacesService)session.getCompApi(PlacesService.COMP_NAME);
步骤二:
创建并进入Place
place=this.placeService.createPlace(
"sampleplace",//Place的唯一名称
"sampleplace",//Place对外的显示名称
EncLevel.ENC_LEVEL_NONE,//加密级别
0);//Place的类型
place.enter();
步骤三:
实现Listener
我们仍然使用观察者模式接收消息。
虽然可以实现PlaceListener接口来接收消息,但toolkit中提供了更加方便使用的PlaceAdapter类。
因为它已经实现了全部PlaceListener接口,我们只需继承它并重载需要改变的方法即可。
首先在调用enter()方法前增加语句:
place.addPlaceListener(newPlaceHandler());
然后在PlaceHandler中重载PlaceAdapter的方法。
作为例子,这里我们只重载entered()方法。
publicclassPlacesHandlerextendsPlaceAdapter{
//用户进入place中以后,该方法会被调用
publicvoidentered(PlaceEventevent){
System.out.println("Placeentered");
}
}
本小节详细的代码参见示例程序AbstractDesktopSharing类。
Meeting类服务
1.ApplicationShare服务(AppShareService):
共享桌面
到此为止,我们已经实现了登录、查找用户、和实时交谈的功能,接下来编写ApplicationShare的代码。
它允许几个在线的用户之间共享、操作某一个用户机器上的桌面或程序。
正如介绍Place时提到的,ApplicationSharing和下面要介绍的Whiteboard实际上都属于Place中的Activity。
开发人员需要进入到一个Place中,添加一个特定类型的Activity,然后才能进入后续操作。
步骤一:
创建ApplicationShareService
meetingFactory=newMeetingFactoryComp(session,null,null,null);
appShareService=newAppShareComp(session);
MeetingFac