BES服务器推送机制分析(一)

来源:互联网 发布:java八大基本数据类型 编辑:程序博客网 时间:2024/05/16 12:37

作者:  邓明轩

 

前言

 

 

数据推送 BlackBerry 用平 BlackBerry 应用

 BlackBerry  样通从服  BlackBerry  设备 端。开发BlackBerry 用平能是 BlackBerry 用集使大功

然而原因一些现使 BlackBerry Enterprise Server (BES)  用平

台的推送能并不能保证数据  BlackBerry  设备,导致应层面的种种问题。实际 BlackBerry 从多成功了解 BES MDS   MDS机制供的 BlackBerry 备。

本章分析 MDS ,让读者了解 BlackBerry 台,壮,稳定 BlackBerry 用。

值得节的方文试总而来 更多的线 MDS 送机 RIM 何官以官不同版本 BlackBerry 持设同场 景下 BlackBerry 也要结合使用

 BlackBerry 行测试,的稳性。

 

 

 

MDS 推送

 

 

MDS 推送架构

 

 

在详细讲 MDS 之前上了 MDS MDS 送架

 

 


从示 BlackBerry 推送 间顺为:

1 第一 MDS/BES 请求 HTTP 式的请 求,在下

2 第二MDS/BES 查询定应求是为合 法的请求MDS/BES 服务源情况确请求对于否接 收请容中论。

3 第三MDS/BES 向应消息通知该请 回消 HTTP 答复返回器。

4 第四MDS/BES 将数备端

5 第五据进理后 MDS/BES 服务消息

6 第六MDS/BES 持设向应步消 一步根据能不生。 从这用服推送通道

而成中有连接个连现异 开发连接在应避。

在详问题先了对于用开 发人送需写工发出求的 备端收推务器的程 橙色的:

 

 

 

 

以下作详

 

 

数据推送命令格式

 

 

BlackBerry 台上的数器发据应逻辑 进行判断据需要推端时 MDS/BES 进行送。 应用 MDS/BES 务器 HTTP 连接通过 HTTP 送一个 POST 求, POST 容。

 POST  URL 为:

http://BES_HOST:BES_PORT/push?DESTINATION=DESINTATION_ADDRESS&PORT=HANDHEL

 


D_APPLICATION_PORT&REQUESTURI=/

下面明:

参数

描述

 

BES_HOST

BlackBerry Enterprise Server  者是 IP

 

BES_PORT

BlackBerry Enterprise Server 般是 8080

 

DESTINATION_ADDRESS

用户备码  (PIN)

 

HANDHELD_APPLICATION_PORT

BlackBerry  需要帧听端口

 

也就是说器通 BES_HOST  BES_PORT 指定连接 MDS/BES 服务

需要BES  务器使用 8080  送应人员 一般 MDS/BES 务器 IP 了。如果 BES 管理 人员过推开发使口。

 URL    push?后面部分用指定据的接者和手设备要帧听端口 DESTINATION_ADDRESS 于指使用者是 持设 PIN HANDHELD_APPLICATION_PORT 于指的端 使用,要的程数据。

除了 URL 送过使 HTTP 指定的属

HTTP 下:

HTTP

描述

 

X-RIM-Push-ID

 

用于 ID ID 以用于 取消的状

 

X-RIM-Push-NotifyURL

用于的接 URL

 

X-RIM-Push-Reliability-Mode

用于性。

 

X-RIM-Push-Deliver-Before

用于推送间。

 

X-RIM-Push-Priority

用于级。

 

 

X-RIM-Push-ID  般建使 URL  合的方式 123@blackberry.com。为

了更,一使作为 ID使一的 ID 有利状态确定注意没有指定MDS/BES 服务会自 动生 ID样就使用 ID 数据 了。 ID @ppg.rim.com 束。

X-RIM-Push-NotifyURL       URL    http://testingserver:7778指定性后MDS/BES 的确认消 HTTP 请求服务发者 HTTP 务器 听指(上例 testingserver 7778 端口过这 端程确认 HTTP X-RIM-Push-ID X-RIM-Push-Status

X-RIM-Push-ID 者是消息,通 X-RIM-Push-Status 指明 据推200 推送400 推送失败据推成功


不能 200 者是 400 需要结合判断本文章节 会详

属性 X-RIM-Push-Reliability-Mode TRANSPORT 或者是 APPLICATION一个 APPLICATIONPREFERRED 涉及场景这里不做描述 果指性为 TRANSPORT 设备准,赖。 可靠 APPLICATION 以数接收为准为应用依 同可设置续章体而用依送更于广 性质到数场景更适用一 数据场景

属性 X-RIM-Push-Deliver-Before  推送最后间前 据仍持设视作 MDS/BES 务器弃。

属性 X-RIM-Push-Priority 于指,指并不 快数推送的结持设选择 none (缺省)low  medium  high。如级为 lowmedium  者是  high 户只指定 high户在到提示对话框

 

 

 

数据推送关键代码

 

 

理论上讲器的数据可以 HTTP 支持 要实是通 HTTP 协议 POST

 java  代码例讲数据推的关键码部。本例代码片为一  Java Application 的部码, Java  Application 服务 J2SE 行, 线程 HTTP POST 求。线程 run

 

 

public  void  run() {

 

 

Random random = new  Random();

String pushId = "pushID:" + random.nextInt(); String data = "What need to be pushed";

 

 

try  {

URL _pushURL = new  URL("http", "testingBES.abc.com", 8080,

"/push?DESTINATION=user1@abc.com&PORT=55100&REQUESTURI=/");

 

 

HttpURLConnection conn = (HttpURLConnection) _pushURL.openConnection();

conn.setDoInput(true); conn.setDoOutput(true); conn.setRequestMethod("POST");

conn.setRequestProperty("X-RIM-PUSH-ID", pushId);

conn.setRequestProperty("X-RIM-Push-NotifyURL",

"http://testingserver:7778");

conn.setRequestProperty("X-RIM-Push-Reliability-Mode",

"APPLICATION");


 

OutputStream out = conn.getOutputStream();

out.write(data.getBytes());

out.close();

 

 

InputStream ins = conn.getInputStream();

int  contentLength = conn.getContentLength();

int  responseCode = conn.getResponseCode(); System.out.println("Response Code is:" + responseCode);

if  (contentLength > 0) {

byte[] someArray = new  byte[contentLength]; DataInputStream dins = new  DataInputStream(ins); dins.readFully(someArray);

System.out.println(new  String(someArray));

} else  {

System.out.println("Content legth of response is 0");

}

 

 

conn.disconnect();

 

 

} catch  (IOException e) { System.err.println("Exception:" + e);

}

}

在以先通 URL HTTP URL 数中第一 为协类型这里使http,第个参为服器名第三参数的端号。 第二对应求中 BES_HOST BES_PORT URL 类的 构造相对 URL DESTINATION PORT 都放在相 URL 码如

URL _pushURL = new  URL("http", "testingBES.abc.com", 8080,

"/push?DESTINATION=user1@abc.com&PORT=55100&REQUESTURI=/");

URL 例后可以 openConnection 接,返回 一个 HttpURLConnection 例。

HttpURLConnection conn = (HttpURLConnection) _pushURL.openConnection();

打开 http 连接实例 setRequestProperty 设置 http 送请

 http ,如:

conn.setRequestProperty("X-RIM-PUSH-ID", pushId);

其中关键 http 性是 X-RIM-Push-Reliability-ModeTRANSPORT 表示该推送是非应用依赖的推送,设置该属性为APPLICATION”表示该推是应用依赖的

                                 

APPLICATION”:

conn.setRequestProperty("X-RIM-Push-Reliability-Mode",


 

 

"APPLICATION");

特别送类服务有特的要 端必须是 4.0 须设置允使行应 推送备的 ROM 也是 4.0 上,手持 支持服务设置面如 BES 理员进行置:

 

 

使用发环  MDS-CS  拟器用依的话需要 MDS/config 目录 rimpublic.property push.application.reliable.ports 一行 同时,如push.application.reliable.ports=10055100

对于持设过手手持 设备端浏览通过  BES  访问过络,务器就会记录该持设是否支持应用依的推 测试的话在测的浏站就 果是虑客动的访客户 端都赖的送。

如果话,对 MDS/BES  送应拒绝 务器The specified delivery method is not possible”的用服务器 序则

java.io.IOException: Server returned HTTP response code: 400 for

URL: http://app...

设置 http 连接的 OutputStream需要写入 OutputStream

中,

需要 MDS/BES 务器是通过 http 现的,所 送应获取 http 连接码判码如

int  responseCode = conn.getResponseCode();

 

 

 

客户端接收关

 

 

客户 BlackBerry 必须 java 需要

BlackBerry  API

客户是启线,开启 http://:<port>(其中 port  是客户 端需,然后从 InputStream,从 InputStream 取服器所

 


推送

下面线 run 法,代码使没有修改

                          

BlackBerry 的标

public  void  run(){ StreamConnection stream = null;

InputStream input = null; MDSPushInputStream pushInputStream=null;

 

 

while  (!_stop)

{

try

{

synchronized(this)

{

_notify =

(StreamConnectionNotifier)Connector.open("http://:55100");

}

 

 

while  (!_stop)

{

stream = _notify.acceptAndOpen();

try

{

input = stream.openInputStream();

pushInputStream= new

MDSPushInputStream((HttpServerConnection)stream, input); DataBuffer db = new  DataBuffer();

byte[] data = new  byte[256];

int  chunk = 0;

 

 

while  ( -1 != (chunk = input.read(data)) )

{

db.write(data, 0, chunk);

}

 

 

pushInputStream.accept(); input.close(); stream.close();

 

 

data = db.getArray();

}


 

catch  (IOException e1)

{

System.err.println(e1.toString());

if  ( input != null  )

{

try

{

input.close();

}

catch  (IOException e2)

{

}

}

if  ( stream != null  )

{

try

{

stream.close();

}

catch  (IOException e2)

{

}

}

}

}

_notify.close();

_notify = null;

}

catch  (IOException ioe)

{

if  ( _notify != null  )

{

try

{

_notify.close();

_notify = null;

}

catch  ( IOException e )

{

}

}

}

}

}


 

以上听的下:

 

_notify = (StreamConnectionNotifier)Connector.open("http://:55100"); 其中  URLhttp://:55100是用55100  听的端口 个线个端侦听在这里使 synchronized 线程行了

控制。

建立过函 acceptAndOpen 当线听的 线程有推下:

stream = _notify.acceptAndOpen();

侦听接的 InputStream InputStream 推送的数 读取 InputStream StreamConnection,然调用 acceptAdnOpen 听端送数

使    InputStream    MDSPushInputStream时在 MDSPushInputStream accept 知服 务器收到应用代码码如下

pushInputStream= new

MDSPushInputStream((HttpServerConnection)stream, input);

……

pushInputStream.accept();

从良好的编程习惯来 ,在连接使用后需要 动关闭所使用的连接 资源, InputStreamStreamConnectionStreamConnectionNotifier 例代码中 到该样例在常处理阶都对这些资进行了关操作。在关这些连接资源的时候对 StreamConnectionNotifier  需要能在  StreamConnectionNotifier  中会 读取 acceptAdnOpen 的数 acceptAdnOpen 处于态。

使用依赖的推送序调 MDSPushInputStream accept 数后 InputStream StreamConnection 闭后 所以 InputStream StreamConnection 非常之重

 

 

 

异步确认消息收代

 

 

异步在服 X-RIM-Push-NotifyURL 性所 的服推送消息程序 可以 HTTP 语言是侦听指口获 MDS/BES 发送 HTTP 取相并返

java 键代 java Application 的一部 侦听线程 run

 

 

public  void  run() {

try  {

System.out.println("Waiting for notification on port" + 7778


+ "...");


 

 

while  (true) {


 

ServerSocket serverSocket = new  ServerSocket(7778);

serverSocket.setSoTimeout(120000);

try  {

Socket clientSocket = serverSocket.accept();

 

 

InputStream input = clientSocket.getInputStream(); StringBuffer str = new  StringBuffer();

int  byteRead = input.read();

while  ((byteRead != -1) && (input.available() > 0)) {

str.append((char) byteRead);

byteRead = input.read();

} System.out.println(str.toString());

OutputStream output = clientSocket.getOutputStream();

 

 

String response = "HTTP/1.0 200 OK";

output.write(response.getBytes());

 

 

output.flush();

output.close();

 

 

input.close();

clientSocket.close();

} catch  (SocketTimeoutException ste) { System.out.println("Notification connection timeout.

Restarting...");

}

serverSocket.close();

}

} catch  (Exception exception) {

exception.printStackTrace();

}

 

 

}

异步比较开一个  Socket  端口 7778断地从该,打 Socket 下:

ServerSocket serverSocket = new ServerSocket(7778);

在异接收中需要注  MDS/BES  服务,应 MDS/BES 一个 200 MDS/BES 认消 可能这样可能消息

消息

OutputStream output = clientSocket.getOutputStream();


 

String response = "HTTP/1.0 200 OK"; output.write(response.getBytes()); output.flush();

output.close();

 

 

 

 

BlackBerry SDK下载

  • BlackBerry Java Plug-in for Eclipse v1.1
  • Java Plug-in for Eclipse Update Site
  • BlackBerry Web Plug-in v2.0
  • BlackBerry Widget SDK v1.0
  • BlackBerry Theme Studio v5.0
  • Plazmic Content Developer’s Kit v4.7
  • BlackBerry smartphone simulators
  •  

    相关链接:

    BES服务器推送机制分析(一)

    BES服务器推送机制分析(二)

    BES服务器推送机制分析(三)