推送
网页推送,是指将经过整理的信息资源以网页的形式迅速转发至用户的界面,实现用户的多
层次需求,使得用户能够自己设定所需要的信息频道,并直接在用户端接收定制信息的实现
方式。
手机推送
内容
手机推送服务是指服务器定向将信息实时送达手机的服务。与常见的轮询方式(伪推送)
相比区别主要在于两点,一是否长联网,二是到达实时性。推送服务是长联网的,一般到达
手机的延迟在0.1-0.5秒左右,而轮询方式(伪推送)不是长联网的,达到延迟时间则根据轮
询时间的不同为1-10分钟,也有延迟1小时或一天的情况。一般来说,自黑莓,苹果和安卓
采用标准长连接推送方式后,手机推送服务就特指能够实时到达的形式。
手机推送服务的原理很简单,就是通过建立一条手机与服务器的连接链路,当有消息需要
发送到手机时,通过此链路发送即可。
** 推送服务的使用流程虽然略有差别但是大致都和 iOS的APNs 相似:**
1、首先是应用程序注册消息推送。
2、 iOS 向 APNs Server 取得deviceToken。应用程序接受deviceToken。
3、应用程序将deviceToken发送给PUSH服务端程序。
4、 服务端程序向APNs服务发送消息。
5、APNs服务将消息发送给iPhone应用程序。
实现方式
1、Android 推送
方案1、使用C2DM服务(Google Cloud Messaging)
简介:Google推出的云消息服务,即第二代的G2DM。
优点:Google提供的服务、原生、简单,无需实现和部署服务端。
缺点:Android版本限制(必须大于2.2版本),该服务在国内不够稳定、需要用户绑定Goo
gle帐号,受限于Google。
方案2、使用XMPP协议(Openfire + Spark + Smack)
简介:基于XML协议的通讯协议,前身是Jabber,已由IETF国际标准化组织完成了标准化工作。
优点:协议成熟、强大、可扩展性强、主要应用于许多聊天系统中,且已有开源的Java版的开发实例androidpn。
缺点:协议较复杂、冗余(基于XML)、费流量、费电,部署硬件成本高。
方案3、使用MQTT协议
简介:轻量级的、基于代理的“发布/订阅”模式的消息传输协议。
优点:协议简洁、小巧、可扩展性强、省流量、省电,应用到企业领域,且已有C++版的服务端组件rsmb。
缺点:不够成熟、实现较复杂、服务端组件 rsmb 不开源,部署硬件成本较高。
方案4、使用第三方推送服务
简介:通过嵌入SDK使用第三方提供的推送服务,主流的有百度云推送,极光推送,智游推送,Urban Airship,个推,PUBNUB,蝴蝶等。
优点:稳定,成熟,节省开发和探索时间,相对自己开发成本低,推送管理界面及统计程序完善。
缺点:有程序嵌入顾虑 [2]
2、IOS推送
推荐使用APNS服务,稳定,方便,美中不足是没有推送到达的回执和统计,不方便产品运营。如对此方面有需求可以使用极光推送,个推蝴蝶等第三方推送服务解决。
3、Win-Phone推送
使用MPNS(Microsoft 推送通知服务),相应速度不错,但推送不带状态,很多功能无法实现。
本次使用第三方推送极光推送
极光推送官网:
引入依赖:
<!-- 极光推送 -->
<dependency>
<groupId>cn.jpush.api</groupId>
<artifactId>jpush-client</artifactId>
<version>3.4.8</version>
</dependency>
<dependency>
<groupId>org.msgpack</groupId>
<artifactId>msgpack</artifactId>
<version>0.6.12</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
实现代码:
private final static String appKey = "5796fd6751ffd45d197d3dc6";
private final static String masterSecret = "d164a42ecd9070137d3b8bd7";
private static JPushClient jPushClient = new JPushClient(masterSecret, appKey);
/* /**
* 推送给设备标识参数的用户
*
* @param registrationId 设备标识
* @param notification_title 通知内容标题
* @param msg_title 消息内容标题
* @param msg_content 消息内容
* @param extrasparam1 扩展字段1
* @param extrasparam2 扩展字段2
* @return 0推送失败,1推送成功
public static int sendToRegistrationId(String registrationId, String notification_title, String msg_title, String msg_content, String extrasparam1, String extrasparam2) {
int result = 0;
try {
PushPayload pushPayload = JpushClientUtil.buildPushObject_all_registrationId_alertWithTitle(registrationId, notification_title, msg_title, msg_content, extrasparam1, extrasparam2);
System.out.println(pushPayload);
PushResult pushResult = jPushClient.sendPush(pushPayload);
System.out.println(pushResult);
if (pushResult.getResponseCode() == 200) {
result = 1;
}
} catch (APIConnectionException e) {
e.printStackTrace();
} catch (APIRequestException e) {
e.printStackTrace();
}
return result;
}
*/
/**
* 发送给安卓指定用户
*
* @param notification_title 通知内容标题
* @param msg_title 消息内容标题
* @param msg_content 消息内容
* @param extrasparam 附加参数
* @param alias 推送别名
* @return 0推送失败,1推送成功
*/
public static int sendToOneAndroid(String notification_title, String msg_title, String msg_content, String extrasparam, String alias) {
int result = 0;
try {
PushPayload pushPayload = JpushClientUtil.buildPushObject_android_all_alertWithTitle(notification_title, msg_title, msg_content, extrasparam, null, alias);
System.out.println(pushPayload);
PushResult pushResult = jPushClient.sendPush(pushPayload);
System.out.println(pushResult);
if (pushResult.getResponseCode() == 200) {
result = 1;
}
} catch (APIConnectionException e) {
e.printStackTrace();
} catch (APIRequestException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 发送给所有安卓用户
*
* @param notification_title 通知内容标题
* @param msg_title 消息内容标题
* @param msg_content 消息内容
* @return 0推送失败,1推送成功
*/
public static int sendToAllAndroid(String notification_title, String msg_title, String msg_content, String extrasparam) {
int result = 0;
try {
PushPayload pushPayload = JpushClientUtil.buildPushObject_android_all_alertWithTitleAll(notification_title, msg_title, msg_content, extrasparam);
System.out.println(pushPayload);
PushResult pushResult = jPushClient.sendPush(pushPayload);
System.out.println(pushResult);
if (pushResult.getResponseCode() == 200) {
result = 1;
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
private static PushPayload buildPushObject_android_all_alertWithTitle(String notification_title, String msg_title, String msg_content, String extrasparam, String type, String value) {
System.out.println("----------buildPushObject_android_registrationId_alertWithTitle");
return PushPayload.newBuilder()
//指定要推送的平台,all代表当前应用配置了的所有平台,也可以传android等具体平台
.setPlatform(Platform.android())
//指定推送的接收对象,all代表所有人,也可以指定已经设置成功的tag或alias或该应应用客户端调用接口获取到的registration id
//根据别名推送
.setAudience(Audience.alias(value))
//jpush的通知,android的由jpush直接下发,iOS的由apns服务器下发,Winphone的由mpns下发
.setNotification(Notification.newBuilder()
//指定当前推送的android通知
.addPlatformNotification(AndroidNotification.newBuilder()
.setAlert(msg_content)
.setTitle(msg_title)
//此字段为透传字段,不会显示在通知栏。用户可以通过此字段来做一些定制需求,如特定的key传要指定跳转的页面(value)
.addExtra("type", extrasparam)
.build())
.build()
)
//Platform指定了哪些平台就会像指定平台中符合推送条件的设备进行推送。 jpush的自定义消息,
// sdk默认不做任何处理,不会有通知提示。建议看文档http://docs.jpush.io/guideline/faq/的
// [通知与自定义消息有什么区别?]了解通知和自定义消息的区别
.setMessage(Message.newBuilder()
.setMsgContent(msg_content)
.setTitle(msg_title)
// .addExtra("message extras key",extrasparam)
.addExtra("status", extrasparam)
.build())
.setOptions(Options.newBuilder()
//此字段的值是用来指定本推送要推送的apns环境,false表示开发,true表示生产;对android和自定义消息无意义
.setApnsProduction(false)
//此字段是给开发者自己给推送编号,方便推送者分辨推送记录
.setSendno(1)
//此字段的值是用来指定本推送的离线保存时长,如果不传此字段则默认保存一天,最多指定保留十天,单位为秒
.setTimeToLive(86400)
.build())
.build();
}
private static PushPayload buildPushObject_android_all_alertWithTitleAll(String notification_title, String msg_title, String msg_content, String extrasparam) {
System.out.println("----------buildPushObject_android_registrationId_alertWithTitle");
return PushPayload.newBuilder()
//指定要推送的平台,all代表当前应用配置了的所有平台,也可以传android等具体平台
.setPlatform(Platform.android())
//指定推送的接收对象,all代表所有人,也可以指定已经设置成功的tag或alias或该应应用客户端调用接口获取到的registration id
// //Audience设置为all,说明采用广播方式推送,所有用户都可以接收到
.setAudience(Audience.all())
//jpush的通知,android的由jpush直接下发,iOS的由apns服务器下发,Winphone的由mpns下发
.setNotification(Notification.newBuilder()
//指定当前推送的android通知
.addPlatformNotification(AndroidNotification.newBuilder()
.setAlert(msg_content)
.setTitle(msg_title)
//此字段为透传字段,不会显示在通知栏。用户可以通过此字段来做一些定制需求,如特定的key传要指定跳转的页面(value)
.addExtra("type", extrasparam)
.build())
.build()
)
//Platform指定了哪些平台就会像指定平台中符合推送条件的设备进行推送。 jpush的自定义消息,
// sdk默认不做任何处理,不会有通知提示。建议看文档http://docs.jpush.io/guideline/faq/的
// [通知与自定义消息有什么区别?]了解通知和自定义消息的区别
.setMessage(Message.newBuilder()
.setMsgContent(msg_content)
.setTitle(msg_title)
.addExtra("status", extrasparam)
.build())
.setOptions(Options.newBuilder()
//此字段的值是用来指定本推送要推送的apns环境,false表示开发,true表示生产;对android和自定义消息无意义
.setApnsProduction(false)
//此字段是给开发者自己给推送编号,方便推送者分辨推送记录
.setSendno(1)
//此字段的值是用来指定本推送的离线保存时长,如果不传此字段则默认保存一天,最多指定保留十天,单位为秒
.setTimeToLive(86400)
.build())
.build();
}
/*private static PushPayload buildPushObject_ios_all_alertWithTitle(String notification_title, String msg_title, String msg_content, String extrasparam) {
System.out.println("----------buildPushObject_ios_registrationId_alertWithTitle");
return PushPayload.newBuilder()
//指定要推送的平台,all代表当前应用配置了的所有平台,也可以传android等具体平台
.setPlatform(Platform.ios())
//指定推送的接收对象,all代表所有人,也可以指定已经设置成功的tag或alias或该应应用客户端调用接口获取到的registration id
.setAudience(Audience.all())
//jpush的通知,android的由jpush直接下发,iOS的由apns服务器下发,Winphone的由mpns下发
.setNotification(Notification.newBuilder()
//指定当前推送的android通知
.addPlatformNotification(IosNotification.newBuilder()
//传一个IosAlert对象,指定apns title、title、subtitle等
.setAlert(notification_title)
//直接传alert
//此项是指定此推送的badge自动加1
.incrBadge(1)
//此字段的值default表示系统默认声音;传sound.caf表示此推送以项目里面打包的sound.caf声音来提醒,
// 如果系统没有此音频则以系统默认声音提醒;此字段如果传空字符串,iOS9及以上的系统是无声音提醒,以下的系统是默认声音
.setSound("sound.caf")
//此字段为透传字段,不会显示在通知栏。用户可以通过此字段来做一些定制需求,如特定的key传要指定跳转的页面(value)
.addExtra("iosNotification extras key", extrasparam)
//此项说明此推送是一个background推送,想了解background看:http://docs.jpush.io/client/ios_tutorials/#ios-7-background-remote-notification
// .setContentAvailable(true)
.build())
.build()
)
//Platform指定了哪些平台就会像指定平台中符合推送条件的设备进行推送。 jpush的自定义消息,
// sdk默认不做任何处理,不会有通知提示。建议看文档http://docs.jpush.io/guideline/faq/的
// [通知与自定义消息有什么区别?]了解通知和自定义消息的区别
.setMessage(Message.newBuilder()
.setMsgContent(msg_content)
.setTitle(msg_title)
.addExtra("message extras key", extrasparam)
.build())
.setOptions(Options.newBuilder()
//此字段的值是用来指定本推送要推送的apns环境,false表示开发,true表示生产;对android和自定义消息无意义
.setApnsProduction(false)
//此字段是给开发者自己给推送编号,方便推送者分辨推送记录
.setSendno(1)
//此字段的值是用来指定本推送的离线保存时长,如果不传此字段则默认保存一天,最多指定保留十天,单位为秒
.setTimeToLive(86400)
.build())
.build();
}
*/
public static void main(String[] args) {
if(JpushClientUtil.sendToAllAndroid("推送给所有Android用户","典韦的推送","测试推送消息","101")==1)
{
System.out.println("推送给所有" +
"Android用户success");
}
/* if (JpushClientUtil.sendToOneAndroid("推送给指定Android用户", "典韦的推送", "测试推送消息", "102", "Dianwei20010922") == 1) {
System.out.println("推送给指定Android用户success");
}*/
}
}
然后这个工具类中提供了一个main方法用来进行推送测试。
首先将上面工具类中的Appkey和secret修改为Jpush开发者平台上应用对应的数据。
然后先打开推送给所有安卓用户的测试方法,运行
{"msg_id":18100019379833432,"sendno":1,"statusCode":0}
推送给所有Android用户success
Process finished with exit code 0