|
6 | 6 |
|
7 | 7 | ## 概述 |
8 | 8 |
|
9 | | -这是 JPush REST API 的 Java 版本封装开发包,是由极光推送官方提供的,一般支持最新的 API 功能。 |
| 9 | +这是 JPush REST API 的 Java 版本封装开发包,此分支主要新增 Http2 支持,关于安装此处不再赘述,可以参考 master 分支下的 ReadMe。 |
10 | 10 |
|
11 | | -对应的 REST API 文档:<http://docs.jpush.io/server/server_overview/> |
12 | 11 |
|
13 | | -本开发包 Javadoc:[API Docs](http://jpush.github.io/jpush-api-java-client/apidocs/) |
14 | | - |
15 | | -版本更新:[Release页面](https://github.com/jpush/jpush-api-java-client/releases)。下载更新请到这里。 |
16 | | - |
17 | | -> 非常欢迎各位开发者提交代码,贡献一份力量,review过有效的代码将会合入本项目。 |
18 | | -
|
19 | | - |
20 | | -## 安装 |
21 | | - |
22 | | -### maven 方式 |
23 | | -将下边的依赖条件放到你项目的 maven pom.xml 文件里。 |
24 | | -> 其中 slf4j 可以与 logback, log4j, commons-logging 等日志框架一起工作,可根据你的需要配置使用。 |
25 | | -
|
26 | | -```Java |
27 | | -<dependency> |
28 | | - <groupId>cn.jpush.api</groupId> |
29 | | - <artifactId>jpush-client</artifactId> |
30 | | - <version>3.2.10</version> |
31 | | -</dependency> |
| 12 | +## 使用 |
| 13 | +本项目使用了 Netty 第三方工具提供的 Http2 支持,建议使用 maven 方式导入,可以参考本项目的 pom.xml。其中有一个依赖需要注意: |
| 14 | +``` |
32 | 15 | <dependency> |
33 | | - <groupId>cn.jpush.api</groupId> |
34 | | - <artifactId>jiguang-common</artifactId> |
35 | | - <version>0.1.4</version> |
| 16 | + <groupId>io.netty</groupId> |
| 17 | + <artifactId>netty-tcnative-boringssl-static</artifactId> |
| 18 | + <version>1.1.33.Fork22</version> |
| 19 | + <classifier>windows-x86_64</classifier> |
36 | 20 | </dependency> |
37 | | - <dependency> |
38 | | - <groupId>com.google.code.gson</groupId> |
39 | | - <artifactId>gson</artifactId> |
40 | | - <version>2.2.4</version> |
41 | | - </dependency> |
42 | | - <dependency> |
43 | | - <groupId>org.slf4j</groupId> |
44 | | - <artifactId>slf4j-api</artifactId> |
45 | | - <version>1.7.5</version> |
46 | | - </dependency> |
47 | | - |
48 | | - <!-- For log4j --> |
49 | | - <dependency> |
50 | | - <groupId>org.slf4j</groupId> |
51 | | - <artifactId>slf4j-log4j12</artifactId> |
52 | | - <version>1.7.5</version> |
53 | | - </dependency> |
54 | | - <dependency> |
55 | | - <groupId>log4j</groupId> |
56 | | - <artifactId>log4j</artifactId> |
57 | | - <version>1.2.17</version> |
58 | | - </dependency> |
59 | 21 | ``` |
60 | | -### jar 包方式 |
61 | | - |
62 | | -请到 [Release页面](https://github.com/jpush/jpush-api-java-client/releases)下载相应版本的发布包。 |
63 | | - |
64 | | - |
65 | | -### 依赖包 |
66 | | -* [slf4j](http://www.slf4j.org/) / log4j (Logger) |
67 | | -* [gson](https://code.google.com/p/google-gson/) (Google JSON Utils) |
68 | | -* [jiguang-commom](https://github.com/jpush/jiguang-java-client-common) |
69 | | - |
70 | | -> 其中 slf4j 可以与 logback, log4j, commons-logging 等日志框架一起工作,可根据你的需要配置使用。 |
71 | | -
|
72 | | -如果不使用 Maven 构建项目,则[项目 libs/ 目录](https://github.com/jpush/jpush-api-java-client/tree/master/libs)下有依赖的 jar 可复制到你的项目里去。 |
73 | | - |
74 | | -## 编译源码 |
75 | | - |
76 | | -> 如果开发者想基于本项目做一些扩展的开发,或者想了解本项目源码,可以参考此章,否则可略过此章。 |
77 | | -
|
78 | | -### 导入本项目 |
79 | | - |
80 | | -* 可以采用 `git clone https://github.com/jpush/jpush-api-java-client.git jpush-api-src` 命令下载源码 |
81 | | -* 如果不使用git,请到[Release页面](https://github.com/jpush/jpush-api-java-client/releases)下载源码包并解压 |
82 | | -* 采用eclipse导入下载的源码工程,推荐采用maven的方式,方便依赖包的管理 |
83 | | -* 假如采用导入普通项目的方式,项目报错,检查Build Path,Libraries |
84 | | - * 依赖jar包都在libs目录下可以找到,没有加入的请添加到Build Path,Libraries |
85 | | - * 默认采用了log4j做日志框架,开发者可根据自己需求替换logback、commons-logging等日志框架 |
86 | | - * 极个别情况下,如果test目录报错,请手动添加test的依赖jar包mockwebserver-2.0.0.jar、okhttp-2.0.0.jar、okio-1.0.0.jar |
87 | | -* 开发者需要注意,将本项目的编码格式设置为UTF-8 |
88 | | - |
89 | | -### 构建本项目 |
90 | | - |
91 | | -可以用 Eclipse 类 IDE 导出 jar 包。建议直接使用 maven,执行命令: |
92 | | - |
93 | | - mvn package |
| 22 | +这个依赖根据平台不同而需要修改其中的 classifier 值,详情参考此网页 http://netty.io/wiki/forked-tomcat-native.html#wiki-h3-16 。 |
94 | 23 |
|
95 | | -### 自动化测试 |
96 | | - |
97 | | -在项目目录下执行命令: |
98 | | - |
99 | | - mvn test |
100 | | - |
101 | | -## 使用样例 |
102 | | - |
103 | | -### 推送样例 |
104 | | - |
105 | | -> 以下片断来自项目代码里的文件:example / cn.jpush.api.examples.PushExample |
106 | | -
|
107 | | -```Java |
108 | | - JPushClient jpushClient = new JPushClient(masterSecret, appKey, 3); |
109 | | - |
110 | | - // For push, all you need do is to build PushPayload object. |
111 | | - PushPayload payload = buildPushObject_all_all_alert(); |
112 | | - |
113 | | - try { |
114 | | - PushResult result = jpushClient.sendPush(payload); |
115 | | - LOG.info("Got result - " + result); |
116 | | - |
117 | | - } catch (APIConnectionException e) { |
118 | | - // Connection error, should retry later |
119 | | - LOG.error("Connection error, should retry later", e); |
120 | | - |
121 | | - } catch (APIRequestException e) { |
122 | | - // Should review the error, and fix the request |
123 | | - LOG.error("Should review the error, and fix the request", e); |
124 | | - LOG.info("HTTP Status: " + e.getStatus()); |
125 | | - LOG.info("Error Code: " + e.getErrorCode()); |
126 | | - LOG.info("Error Message: " + e.getErrorMessage()); |
127 | | - } |
| 24 | +## 关于接口调用 |
| 25 | +首先要调用 NettyHttp2Client 的构造函数(之前用的是 NativeHttpClient): |
128 | 26 | ``` |
129 | | - |
130 | | -进行推送的关键在于构建一个 PushPayload 对象。以下示例一般的构建对象的用法。 |
131 | | - |
132 | | -* 快捷地构建推送对象:所有平台,所有设备,内容为 ALERT 的通知。 |
133 | | - |
134 | | -```Java |
135 | | - public static PushPayload buildPushObject_all_all_alert() { |
136 | | - return PushPayload.alertAll(ALERT); |
137 | | - } |
138 | | -``` |
139 | | - |
140 | | -* 构建推送对象:所有平台,推送目标是别名为 "alias1",通知内容为 ALERT。 |
141 | | - |
142 | | -```Java |
143 | | - public static PushPayload buildPushObject_all_alias_alert() { |
144 | | - return PushPayload.newBuilder() |
145 | | - .setPlatform(Platform.all()) |
146 | | - .setAudience(Audience.alias("alias1")) |
147 | | - .setNotification(Notification.alert(ALERT)) |
148 | | - .build(); |
149 | | - } |
| 27 | +NettyHttp2Client client = new NettyHttp2Client(authCode, proxy, conf, _baseUrl); |
150 | 28 | ``` |
| 29 | +前三个参数和 NativeHttpClient 一样,最后一个参数要传入一个 host url。可以参考 PushClient 的做法。 |
151 | 30 |
|
152 | | -* 构建推送对象:平台是 Android,目标是 tag 为 "tag1" 的设备,内容是 Android 通知 ALERT,并且标题为 TITLE。 |
153 | | - |
154 | | -```Java |
155 | | - public static PushPayload buildPushObject_android_tag_alertWithTitle() { |
156 | | - return PushPayload.newBuilder() |
157 | | - .setPlatform(Platform.android()) |
158 | | - .setAudience(Audience.tag("tag1")) |
159 | | - .setNotification(Notification.android(ALERT, TITLE, null)) |
160 | | - .build(); |
161 | | - } |
| 31 | +发送单个请求的做法和之前一致,可以参考 example 下的相关示例。NettyHttp2Client 新增发送批量请求的接口: |
162 | 32 | ``` |
163 | | - |
164 | | -* 构建推送对象:平台是 iOS,推送目标是 "tag1", "tag_all" 的并集,推送内容同时包括通知与消息 - 通知信息是 ALERT,角标数字为 5,通知声音为 "happy",并且附加字段 from = "JPush";消息内容是 MSG_CONTENT。通知是 APNs 推送通道的,消息是 JPush 应用内消息通道的。APNs 的推送环境是“生产”(如果不显式设置的话,Library 会默认指定为开发) |
165 | | - |
166 | | -```Java |
167 | | - public static PushPayload buildPushObject_ios_tagAnd_alertWithExtrasAndMessage() { |
168 | | - return PushPayload.newBuilder() |
169 | | - .setPlatform(Platform.ios()) |
170 | | - .setAudience(Audience.tag_and("tag1", "tag_all")) |
171 | | - .setNotification(Notification.newBuilder() |
172 | | - .addPlatformNotification(IosNotification.newBuilder() |
173 | | - .setAlert(ALERT) |
174 | | - .setBadge(5) |
175 | | - .setSound("happy") |
176 | | - .addExtra("from", "JPush") |
177 | | - .build()) |
178 | | - .build()) |
179 | | - .setMessage(Message.content(MSG_CONTENT)) |
180 | | - .setOptions(Options.newBuilder() |
181 | | - .setApnsProduction(true) |
182 | | - .build()) |
183 | | - .build(); |
184 | | - } |
| 33 | +NettyHttp2Client.setRequest(HttpMethod, Queue<Http2Request>).execute(BaseCallback) |
185 | 34 | ``` |
186 | | - |
187 | | -* 构建推送对象:平台是 Andorid 与 iOS,推送目标是 ("tag1" 与 "tag2" 的交集)并("alias1" 与 "alias2" 的交集),推送内容是 - 内容为 MSG_CONTENT 的消息,并且附加字段 from = JPush。 |
188 | | - |
189 | | -```Java |
190 | | - public static PushPayload buildPushObject_ios_audienceMore_messageWithExtras() { |
191 | | - return PushPayload.newBuilder() |
192 | | - .setPlatform(Platform.android_ios()) |
193 | | - .setAudience(Audience.newBuilder() |
194 | | - .addAudienceTarget(AudienceTarget.tag("tag1", "tag2")) |
195 | | - .addAudienceTarget(AudienceTarget.alias("alias1", "alias2")) |
196 | | - .build()) |
197 | | - .setMessage(Message.newBuilder() |
198 | | - .setMsgContent(MSG_CONTENT) |
199 | | - .addExtra("from", "JPush") |
200 | | - .build()) |
201 | | - .build(); |
202 | | - } |
| 35 | +示例代码如下: |
203 | 36 | ``` |
204 | | - |
205 | | -* 构建推送对象:推送内容包含SMS信息 |
206 | | - |
207 | | -```Java |
208 | | - public static void testSendWithSMS() { |
209 | | - JPushClient jpushClient = new JPushClient(masterSecret, appKey); |
| 37 | +public void testSendPushesReuse() { |
| 38 | + ClientConfig config = ClientConfig.getInstance(); |
| 39 | + String host = (String) config.get(ClientConfig.PUSH_HOST_NAME); |
| 40 | + NettyHttp2Client client = new NettyHttp2Client(ServiceHelper.getBasicAuthorization(APP_KEY, MASTER_SECRET), |
| 41 | + null, config, host); |
| 42 | + Queue<Http2Request> queue = new LinkedList<Http2Request>(); |
| 43 | + String url = (String) config.get(ClientConfig.PUSH_PATH); |
| 44 | + PushPayload payload = buildPushObject_all_all_alert(); |
| 45 | + for (int i=0; i<100; i++) { |
| 46 | + queue.offer(new Http2Request(url, payload.toString())); |
| 47 | + } |
210 | 48 | try { |
211 | | - SMS sms = SMS.content("Test SMS", 10); |
212 | | - PushResult result = jpushClient.sendAndroidMessageWithAlias("Test SMS", "test sms", sms, "alias1"); |
213 | | - LOG.info("Got result - " + result); |
214 | | - } catch (APIConnectionException e) { |
215 | | - LOG.error("Connection error. Should retry later. ", e); |
216 | | - } catch (APIRequestException e) { |
217 | | - LOG.error("Error response from JPush server. Should review and fix it. ", e); |
218 | | - LOG.info("HTTP Status: " + e.getStatus()); |
219 | | - LOG.info("Error Code: " + e.getErrorCode()); |
220 | | - LOG.info("Error Message: " + e.getErrorMessage()); |
| 49 | + long before = System.currentTimeMillis(); |
| 50 | + LOG.info("before: " + before); |
| 51 | + client.setRequestQueue(HttpMethod.POST, queue).execute(new NettyHttp2Client.BaseCallback() { |
| 52 | + @Override |
| 53 | + public void onSucceed(ResponseWrapper wrapper) { |
| 54 | + PushResult result = BaseResult.fromResponse(wrapper, PushResult.class); |
| 55 | + LOG.info("Got result - " + result); |
| 56 | + } |
| 57 | + }); |
| 58 | + } catch (Exception e) { |
| 59 | + e.printStackTrace(); |
221 | 60 | } |
222 | 61 | } |
223 | 62 | ``` |
224 | | - |
225 | | -### 统计获取样例 |
226 | | - |
227 | | -> 以下片断来自项目代码里的文件:example / cn.jpush.api.examples.ReportsExample |
228 | | -
|
229 | | -```Java |
230 | | - JPushClient jpushClient = new JPushClient(masterSecret, appKey); |
231 | | - try { |
232 | | - ReceivedsResult result = jpushClient.getReportReceiveds("1942377665"); |
233 | | - LOG.debug("Got result - " + result); |
234 | | - |
235 | | - } catch (APIConnectionException e) { |
236 | | - // Connection error, should retry later |
237 | | - LOG.error("Connection error, should retry later", e); |
238 | | - |
239 | | - } catch (APIRequestException e) { |
240 | | - // Should review the error, and fix the request |
241 | | - LOG.error("Should review the error, and fix the request", e); |
242 | | - LOG.info("HTTP Status: " + e.getStatus()); |
243 | | - LOG.info("Error Code: " + e.getErrorCode()); |
244 | | - LOG.info("Error Message: " + e.getErrorMessage()); |
245 | | - } |
246 | | -``` |
247 | | - |
248 | | -### Tag/Alias 样例 |
249 | | - |
250 | | -> 以下片断来自项目代码里的文件:example / cn.jpush.api.examples.DeviceExample |
251 | | -
|
252 | | -* 获取Tag Alias |
253 | | -```Java |
254 | | - try { |
255 | | - TagAliasResult result = jpushClient.getDeviceTagAlias(REGISTRATION_ID1); |
256 | | - |
257 | | - LOG.info(result.alias); |
258 | | - LOG.info(result.tags.toString()); |
259 | | - } catch (APIConnectionException e) { |
260 | | - LOG.error("Connection error. Should retry later. ", e); |
261 | | - } catch (APIRequestException e) { |
262 | | - LOG.error("Error response from JPush server. Should review and fix it. ", e); |
263 | | - LOG.info("HTTP Status: " + e.getStatus()); |
264 | | - LOG.info("Error Code: " + e.getErrorCode()); |
265 | | - LOG.info("Error Message: " + e.getErrorMessage()); |
266 | | - } |
267 | | -``` |
268 | | - |
269 | | -* 绑定手机号 |
270 | | - |
271 | | -```Java |
272 | | - try { |
273 | | - DefaultResult result = jpushClient.bindMobile(REGISTRATION_ID1, "13000000000"); |
274 | | - LOG.info("Got result " + result); |
275 | | - } catch (APIConnectionException e) { |
276 | | - LOG.error("Connection error. Should retry later. ", e); |
277 | | - } catch (APIRequestException e) { |
278 | | - LOG.error("Error response from JPush server. Should review and fix it. ", e); |
279 | | - LOG.info("HTTP Status: " + e.getStatus()); |
280 | | - LOG.info("Error Code: " + e.getErrorCode()); |
281 | | - LOG.info("Error Message: " + e.getErrorMessage()); |
282 | | - } |
283 | | -``` |
284 | | - |
285 | | -### Schedule 样例 |
286 | | - |
287 | | -> 以下片断来自项目代码里的文件:example / cn.jpush.api.examples.ScheduleExample |
288 | | -
|
289 | | -```Java |
290 | | - JPushClient jpushClient = new JPushClient(masterSecret, appKey); |
291 | | - String name = "test_schedule_example"; |
292 | | - String time = "2016-07-30 12:30:25"; |
293 | | - PushPayload push = PushPayload.alertAll("test schedule example."); |
294 | | - try { |
295 | | - ScheduleResult result = jpushClient.createSingleSchedule(name, time, push); |
296 | | - LOG.info("schedule result is " + result); |
297 | | - } catch (APIConnectionException e) { |
298 | | - LOG.error("Connection error. Should retry later. ", e); |
299 | | - } catch (APIRequestException e) { |
300 | | - LOG.error("Error response from JPush server. Should review and fix it. ", e); |
301 | | - LOG.info("HTTP Status: " + e.getStatus()); |
302 | | - LOG.info("Error Code: " + e.getErrorCode()); |
303 | | - LOG.info("Error Message: " + e.getErrorMessage()); |
304 | | - } |
305 | | -``` |
306 | | - |
307 | | -### Custom Client 样例 |
308 | | - |
309 | | -> 一下片断来自项目代码里面的文件:example / cn.jpush.api.examples.ClientExample |
310 | | -
|
311 | | -* 配置的SSLVersion表示指定至少支持的协议版本,也可能支持其他多个协议版本,最终支持的协议版本列表取决于JRE和运行环境 |
312 | | -```Java |
313 | | - public static void testCustomClient() { |
314 | | - ClientConfig config = ClientConfig.getInstance(); |
315 | | - config.setMaxRetryTimes(5); |
316 | | - config.setConnectionTimeout(10 * 1000); // 10 seconds |
317 | | - config.setSSLVersion("TLSv1.1"); // JPush server supports SSLv3, TLSv1, TLSv1.1, TLSv1.2 |
318 | | - |
319 | | - JPushClient jPushClient = new JPushClient(masterSecret, appKey, null, config); |
320 | | - } |
321 | | - |
322 | | - public static void testCustomPushClient() { |
323 | | - ClientConfig config = ClientConfig.getInstance(); |
324 | | - config.setApnsProduction(false); // development env |
325 | | - config.setTimeToLive(60 * 60 * 24); // one day |
326 | | - |
327 | | - // config.setGlobalPushSetting(false, 60 * 60 * 24); // development env, one day |
328 | | - |
329 | | - JPushClient jPushClient = new JPushClient(masterSecret, appKey, null, config); // JPush client |
330 | | - |
331 | | - // PushClient pushClient = new PushClient(masterSecret, appKey, null, config); // push client only |
332 | | - |
333 | | - } |
334 | | -``` |
| 63 | +此为链接复用的接口,相对于循环发送单个请求,效率明显提高。可以参考 PushClientTest,写一下测试用例验证一下。 |
0 commit comments