BES 推送应用实例演示与分析(二)

作者: 杨江

 

第三 部分     手机   E clip se

 

 

 

 

 

1 .     打开 Eclip se ,

 

 

 

2 .     Fi le I m p o r t , Gene ral à Existin g P r o jec ts t o Wo r kspace


 

 


 

 


 

 


 

 

 


 

 

 

 

 

 

第四 部分     核心代码 分析

 

Bl ac kB e rr y Pu s h 架构

在分析样例代码之前,首先让我们从整体上了解   B lack B err y   Pu sh

 

更加详细的 B lack B err y 推送机制的分析和介绍,请参考黑莓官方网站,以及参考资 料“ B ES 服务器推送机制分析”。

 

 


 

 

从示意图中,我们可以看到,在   B lack B err y 用平台上的数据推送从整体上可以分

为六步,按时间顺序分别为:

 

1       应用服务器向 MD S/ B E S 服务器发送推送请求,该请求为 H TTP POST 请求。

2/3 M D S/ B ES 服务 做必要的权限和数据监测,告知应用服务器推送请求是否被 接受并将被执行。

4 MD S / B ES 服务器通过 B lack B err y Inf rast ru ct u re 和无线网络把数 推送到手持设 备端。

5 手持设备收到数 后,向 MD S/ B ES 器反馈。

6 MD S / B ES 服务器告知应用服务器其推送数据是否送达手 设备。

 

 

ECL

B lack B err y Pu sh 系统架构上看,从服务器端 Pu sh 数据到手机 ,要经过多个服 务器和网络甚至无线基站,整个流程相当复杂。幸运的是,从应用开发的角度,程 序员可以不考虑 Pu sh 的复杂底层实现,而只需简单地发送 Pu sh 求并监听 Pu sh 请求的处理状态,客户端监听并接受推送数据即可:

 

1       服务器程序向   MD S/ B E S   服务器发送推送请求,所发送的请求为   H TTP   POST

请求。

2       手持设备上的   Java   客户端程序接收   pu sh   来的数据,做出灯光闪 / 振铃 等提示,甚至修改桌面图标提示用户, 户打开程序界面查看数据。

3       服务器程序从 MD S/ B E S 服务器获得推送请求是否完成的状态信息。

 


Ja v a   E CL 服务器代 分析

 

核心代码说 Ja v a 类列表

 

 

 

Java 版本 ECL 服务器程序是一个命令行程序,根据命令行参数把指定 exc el 表格中 的联系人列表 c ont act li st 数据推送给指定的手机上。

 

1 .     主程序:是 ec lTim e dU pda te.ja va ,这是一个 main() 方法的控制 序,根 据不同参数调用两个 P usher 类做 Brow se r Push Custom i z e P ush

2 .     核心   P ush :由

B row s e rCha nne lP usher .j a va/Custom AppPushe r.ja va/P usher .java 三个类 成。

3 .     服务器配置信息 MdsP rope rties.ja va 等四个 用于读取配置文本文件,让

EC L 服务器主程序   MDS/B ES 服务器   I P 地址端口号等信息。

4 .     数据访问: Da taRea d e r. java 通过   J DB C - OD B C 接口读取   Ex ce l 表单数据。

 

 

EC L 服务器程序各个 J a va 类的功能说明列表 下:

 

Java Class

De scr ip tion

 

 

eclTi m edUpdate. j ava

包含 main() 方法的控 程序,根据不同参数调 用两个 P usher 类做 B ro wse r Push Custom iz e

P ush

Bro w s erChannel P usher. j ava

 

Custom AppPushe r.ja va

 

Pushe r .java

核心的服务器   P ush 代码,包括   B row s e r pushe r

  c ustom 应用   pushe r

 

B row s e r pushe r c usto m 应用 pushe r 的共同父 类是 P usher .java

 

 

 

 

MdsP rope rties.ja va Ca tche rPrope rties.java Cha nne lP rope rties.ja va S trong l y T y pe dP ropertiesSet.java

MdsP rope rties.ja va 读取   MDS 服务器参数,比如

B ES 服务器主机名 / I P 地址 / 端口号。

 

Ca tche rPrope rties.ja va 读取手机端监听端口。

 

Cha nne lP rope rties.ja va 读取浏览器 P ush 相关参 数。

 

配置文 样本:

# The name of the machine that hosts the

MDS   push server

BesHostName = localhost

 

 

 

# The port on which the MDS Push service is listening.

# (Set equal to the

"WebServer.listen.port"   property for the

MDS.)

BesPushPort   = 8080

 

# The port that the device -side catcher app is listening on.

DeviceListenPort = 911

Da taRea d e r.ja v a

S prea dshee tP rop e rties.ja va

 

Da taRea d e r 通过 J DB C - OD B C 接口读取 Ex ce l 单数据 紧急情况联系人列表。

 

 

 

e c lTime d U pd a te .j a v a 代码分析

 

数构造 P us her (BrowserC ha nn elP us her 或者 C ust omAp pPusher ) 作为整个服务器端推送数据程序的入口 eclTimed Up d at e.java 是一 标准的 J2 SE 程序。

 

main ( ) 方法中首先分析第一个参数。如果参数值是 c h ann el ,则 pu sh er B ro w serCh ann el Pu sh er 类;如果参数值是 c at c h er ,则构造 p u sh er Cust omAp p P u sh er 类。

 

 

public static void main(String[] args)

// Process command-line arguments

if     (args. length >= 1) {

if     (args[0].equalsIgnoreCase( "channel" )) {

// Construct a pusher that sends to a browser channel.

pusher = new     BrowserChannelPusher ();  //Browser push 也是一个很 趣的

} else     if     (args[0].equalsIgnoreCase( "catcher" )) {

// Construct a pusher that sends to a custom catcher.

pusher = new     CustomAppPusher ();

}

}

 

 

 

数从 件中 Bl a ckBe rry P IN 列表

例如从   simu lat o remail.tx t 文件中读取到的   PIN 码为黑莓模拟器的   PIN

21 00 00 0a

 

提示: B lack B err y MD S/B ES 服务器支持以手机 PIN 码和 email 地址 别要推送的目 标手机。在 ECL 样例程序中是使用手机 PIN 码。


 

if (args.length >= 2) {

emailListFile = args[1];

}

 

// Get the list of emails to push to.

List recipientEmails = getRecipients(emailListFile);

 

 

 

 

数从 ex cel 读取 ECL 联系 列表

在这里调用 D at aRea d er 类访问 Exc el 表,读取每个组和每个人的联系方式,并通过 pu sh e r.add Co nt ac t ( d at a Field s) ; 方法把数据传 pu sh e r ,最后调用 pu sh e r.f in is h ed Co n st r u c t ion () ; 方法告 pu sh er 数据全部读取完毕。 P u sh er 会把所有 联系人方式构造成一 x ml 字符串保存起来以备下一步调用 pu sh e r.sen d ToH an dh el d(c u rRec ip ient ) ; 进行发

 

 

// Fetch the group names from the spreadsheet.

Vector groupDescription = dataReader.getGroupList();

 

// Assemble the data of all contacts (from all groups) that we

// will push to handhelds.

for     ( int     i = 0;  i < groupDescription.size();  i++) {

 

// Define the current group.

pusher.beginGroup((String)groupDescription.elementAt(i));

 

// Add all its members.

Vector groupContactList = dataReader.getContactList(

(String)groupDescription.elementAt(i));

for     ( int     j = 0;  j < groupContactList.size();  j++) {

String[] dataFields = dataReader.getContactData(

(String)groupContactList.elementAt(j));

pusher.addContact(dataFields);

}

}

 

// Indicate that we're done building the contacts list.  After,

// the pusher is ready to send the message multiple times.

pusher.finishedConstruction();

 

 

p us her.sen dT oH a n dh eld () 黑莓

做一个 Fo r 循环,多次调用 pu sh e r.sen d ToH an dh el d (c u rRec ip ie nt ) B ES/MD S 务器把数据发送到各个手机上面。

 

 


 

// Push the message we just built to all recipients.

for     ( int     i = 0;  i < recipientEmails.size();  i++) {

 

String curRecipient = (String)recipientEmails.get(i);

try     {

System. out .print( "Contacting BES for " + curRecipient);

pusher.sendToHandheld(curRecipient); System. out .println( " - successful push." );

 

} catch   (Pusher.MDSConnectionException ex) {

// Unable to connect to MDS.  The condition is unlikely

// to be temporary so abort.

System. out .println( " - " + ex.getMessage());

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Pu s he r.j av a 代码分析

break ;

 

} catch   (Pusher.MDSResponseException ex) {

// Connected OK but MDS responded with error.  Log it and

// try the next email.

System. out .println( " - MDS responded with "

+ ex.getMessage());

 

} catch   (Exception ex) {

// Unexpected error.  Log a full stack trace and try the

// next email.

System. out .println( " - unexpected error:" );

ex.printStackTrace();

}

}

 

 

 

 

 

Pu sh e r.java 代码实际上包括两部分内容,一部分是准备要推送的数据,一部分是真

正的推送操作。

 

B egin Group ( ) ad d Cont a c t ( ) f in ish e d Con s t ru ct ion ( ) 三个方法是用来准备要推送的数 据。主逻辑程序多次调用这三个方 告诉 Pusher 有哪些联系人数据要推送。 Pusher 会把这些数据拼装成一个 html 或者是一个大文本,并最终推送给手机浏 览器或者手机客户端程序 writeTo(OutputStream) 方法用来把前面三个方法 构造出来的数据写到输出流中。

 

注意:以上 4 个方法和 push 无关,更好的做法应该是把他们分离出去做一个独 立的数据构造类。

 

Pusher.java 代码的核心方法 sendToHandheld(String recipientEmail) 。该方法构造标准 http POST 请求给 MDS/BES 服务器,通 过参数 DESTINATION 指定要把数据 push 给哪些人(参数值可以是 email 地址或 者是手机 PIN 码),参 PORT 告知要把数据推送到手机上面哪个端口(例子代码 中是端口 911 )。


 

/**


 

* Pushes the already - constructed message to the indicated recipient.  May

* be used many times, but only in the "sending" state.

*/

public     void     sendToHandheld(String recipientEmail)

throws   IOException, MDSConnectionException, MDSResponseException


{

HttpURLConnection conn = null ;

OutputStream out = null ;

 

try   {

 

// Build the URL to define our connection to the BES.

URL url = new     URL( "http" , _props .getBesHostName(),

_props .getBesPushPort(),

"/push?DESTINATION=" + recipientEmail

+ "&PORT=" + getDevicePort()

+ "&REQUESTURI=/" );

 

conn = (HttpURLConnection)url.openConnection();

conn.setDoOutput(true ); //to post data

 

conn.setRequestMethod("POST" );

 

   

 

establishRequestHeaders(conn);

 

//write the data to the http connection

out = conn.getOutputStream();

writeTo(out);

 

// Check the MDS's response so that we report an error if the push

// was unsuccessful.

int     responseCode = conn.getResponseCode();

if   (responseCode != HttpURLConnection. HTTP_OK ) {

String serverMessage = conn.getResponseMessage();

throw     new     MDSResponseException(

"HTTP-" + responseCode + ": " + serverMessage);

}

 

 

 

 

核心代码说 Ja v a 类列表

客户端代码由三个   Java 类,两个图标文件, B lack B err y 应用描述文 构成。

 

 

 

 

 

EC L 客户端程序三个 J a va 类的功能说明列表 下:

 


 

Java Class

 

 

 

 

Pushe d D a t a Lis t ener

在指定端口 911 上监听 push 过来的数据。收到 后调用 Da taSt or e 改手机上应用的图标以提 示用户有更新过的联系人列表。

 

 

 

 

EC LApplic a t i on

客户端主程序,通过配置,最终会在客户端启 动两个 J a va 进程:后台运行的

P ushed Da ta L ist e ne r 来监听   push 过来的数据;

前台   GU I 界面   EC L App li ca ti on 和内部类

Ec lS c re e n 用于展现 到的 push 数据 联系人列 表。

 

Da taSt or e

使用

net.rim.device.api.system.PersistentStore

保存最 ECL 人员 表数据。

 

 

 

E C L 客户端程序的 个入口 (A lt e r nat e E n t ry P o i nt s )

EC L 客户端程序是如 自动启动监听程序的?又是如何区分点击 icon 启动 GU I 面程序的呢?答案在应用描述文件 B lac k B e rr y _App_De sc riptor.x ml 和主程序的 main() 方法上。

 

打开 B lac k B e rr y _App_ De sc riptor.x ml ,在 Applica ti on 标签栏目里面,你会看到

Auto- run o n sta rtup 中。这样 EC L S a mpl e 程序会在手机启动过程中自动地启 动,产生一个后台 J a va 进程监听 P ush 数据。

 

Alter na te En tr y P oint s 栏目中,设置了一个参数 Applica ti on a r g ume nt g ui ,并 单独设置了程序 Titl e I c on ,因此程序安 后在“下载”目录里面出现一个应用 图标。点击图标将产生一个前台 GU I 进程来 取并显示 P ush 过来的数据。

 


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 
 

 

 

BlackBerry SDK下载

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值