zoukankan      html  css  js  c++  java
  • 百度消息推送REST API探究

    一、百度云推送介绍

    云推送(Push)是百度开放云向开发者提供的消息推送服务;通过利用云端与客户端之间建立稳定、可靠的长连接来为开发者提供向客户端应用推送实时消息服务。

    百度云推送服务支持推送三种类型的消息:

    1、推送通知 :向移动端推送展现在系统通知栏的通知消息。

    2、推送消息 :以透传的方式将开发者自定义的内容发送到客户端。开发者可以预先在客户端设定好规范,进行消息定制化。

    3、推送富媒体 :推送图片、视频、音频、网址等形式的富媒体信息。

    支持向所有用户或根据标签分类向特定用户群体推送消息;支持更多自定义功能(如自定义内容、后续行为、样式模板等);提供用户信息及通知消息统计信息。现在又新增了基于地理位置的推送(LBS推送),目前LBS推送还处于测试阶段。

    好了,废话不多说了,要了解详细使用请查看官方文档,首先进入百度开放云平台:

    http://developer.baidu.com/wiki/index.php?title=docs

    可以看到REST API部分

    二、REST API介绍

    首先进入概述部分,就可以看到有如下内容:


    第一句话“为方便开发者更灵活方便的使用云推送服务进行开发,云推送服务按照百度HTTP Open API 规范为开发者提供REST风格的 HTTP 和 HTTPS 服务端接口。”

    很多读者可能不明白什么是REST风格,REST是一个主要的Web服务设计模式,定义了一组体系架构原则。

    详细请看:http://baike.baidu.com/link?url=g6lVSlIDxUUzVuQy1MYhMx98d_JTE8Tj2woEpjrIY9vwghxGM3eCztXcU_gFkIwLenP5_9F0l3qhV027C9I61K

    接下来就是请求格式

    http[s]://channel.api.duapp.com/rest/2.0/channel/{resource}?{query_string}
    做过Web开发的朋友会发现这里的请求格式其实和我们使用的Get方式没有什么区别,所以现在我们只需要去关注定义的参数

    直接找示例(这里给初学的朋友一个建议,一般在看文档的时候盲目的无从下手的时候最好且最有效的办法就是找示例代码,参照示例代码看文档)

    推送给所有人请求示例

    Android:
    
    http[s]://channel.api.duapp.com/rest/2.0/channel/channel?method=push_msg&apikey=Ljc710pzAa99GULCo8y48NvB&sign=8777F555E8C16715EBA5C85341684C58&timestamp=12344543232&expires=1238747373&v=1&device_type=3&push_type=3&message_type=1&messages="{"title":"","description":"test"}"&msg_keys="testkey"
    
    iOS:
    
    http[s]://channel.api.duapp.com/rest/2.0/channel/channel?method=push_msg&apikey=Ljc710pzAa99GULCo8y48NvB&sign=8777F555E8C16715EBA5C85341684C58&timestamp=12344543232&expires=1238747373&v=1&device_type=4&push_type=3&message_type=1&messages="{"aps":{"alert":"test"}}"

    IOS暂时不看,我们先来看看Android中的各个参数是什么,接下来要做的事情很简单,就是找到这些参数。

    参数名称类型是否必需描述
    methodstring方法名,必须存在:push_msg。
    apikeystring访问令牌,明文AK,可从此值获得App的信息,配合sign中的sk做合法性身份认证。
    user_idstring用户标识,在Android里,channel_id + userid指定某一个特定client。不超过256字节,如果存在此字段,则只推送给此用户。
    push_typeuint推送类型,取值范围为:1~3

    1:单个人,必须指定user_id 和 channel_id (指定用户的指定设备)或者user_id(指定用户的所有设备)

    2:一群人,必须指定 tag

    3:所有人,无需指定tag、user_id、channel_id

    channel_iduint通道标识
    tagstring标签名称,不超过128字节
    device_typeuint设备类型,取值范围为:1~5

    云推送支持多种设备,各种设备的类型编号如下:

    1:浏览器设备;

    2:PC设备;

    3:Andriod设备;

    4:iOS设备;

    5:Windows Phone设备;

    如果存在此字段,则向指定的设备类型推送消息。 默认为android设备类型。

    message_typeuint消息类型

    0:消息(透传给应用的消息体)

    1:通知(对应设备上的消息通知)

    默认值为0。

    messagesstring指定消息内容,单个消息为单独字符串。如果有二进制的消息内容,请先做 BASE64 的编码。

    当message_type为1 (通知类型),请按以下格式指定消息内容。
    通知消息格式及默认值:

    {
    //android必选,ios可选
    "title" : "hello" ,   
    “description: "hello world" 
    
    //android特有字段,可选
    "notification_builder_id": 0,
    "notification_basic_style": 7,
    "open_type":0,
    "net_support" : 1,
    "user_confirm": 0,
    "url": "http://developer.baidu.com",
    "pkg_content":"",
    "pkg_name" : "com.baidu.bccsclient",
    "pkg_version":"0.1",
    
    //android自定义字段
    "custom_content": {
    	"key1":"value1", 
    	"key2":"value2"
    	},  
    
    //ios特有字段,可选
    "aps": {
    	"alert":"Message From Baidu Push",
    	"sound":"",
    	"badge":0
    	},
    
    //ios的自定义字段
    "key1":"value1", 
    "key2":"value2"
    }
    

    注意:

    • 当description与alert同时存在时,ios推送以alert内容作为通知内容
    • 当custom_content与 ios的自定义字段"key":"value"同时存在时,ios推送的自定义字段内容会将以上两个内容合并,但推送内容整体长度不能大于256B,否则有被截断的风险。
    • 此格式兼容Android和ios原生通知格式的推送。
    • 如果通过Server SDK推送成功,Android端却收不到通知,解决方案请参考该:问题
    msg_keysstring消息标识。

    指定消息标识,必须和messages一一对应。相同消息标识的消息会自动覆盖。特别提醒:该功能只支持android、browser、pc三种设备类型。

    message_expiresuint指定消息的过期时间,默认为86400秒。必须和messages一一对应。
    deploy_statusuint部署状态。指定应用当前的部署状态,可取值:

    1:开发状态

    2:生产状态

    若不指定,则默认设置为生产状态。特别提醒:该功能只支持ios设备类型。

    timestampuint用户发起请求时的unix时间戳。本次请求签名的有效时间为该时间戳+10分钟。
    signstring调用参数签名值,与apikey成对出现。

    详细用法,请参考:签名计算算法

    expiresuint用户指定本次请求签名的失效时间。格式为unix时间戳形式。
    vuintAPI版本号,默认使用最高版本。

    三、推送案例

    http[s]://channel.api.duapp.com/rest/2.0/channel/channel?method=push_msg    //这个是方法名,不用理会

    &apikey=Ljc710pzAa99GULCo8y48NvB                     //apikey  

    &sign=8777F555E8C16715EBA5C85341684C58    //下面有详细介绍

    &timestamp=12344543232     //就默认

    &expires=1238747373   //保持默认

    &v=1                             //保持默认

    &device_type=3                //3 Android设备

    &push_type=3     //3 所有人

    &message_type=1     //1 通知

    &messages="{"title":"","description":"test"}"     //消息内容

    &msg_keys="testkey"    //使用一个不重复的字符串(唯一区别消息)

    可以看到参数中有一个apikey,好吧,先去创建一个移动应用。

    创建应用地址:http://developer.baidu.com/console?#app/project


    再进行推送设置


    可以看到上面有一个快速示例,将示例代码下载并在Eclipse中(Android开发环境中)运行。

               


    现在apikey已经能够获取了,下面再来看一下sign如何获取

    云推送服务API使用的签名算法如下:

    获取请求的http method

    获取请求的url,包括host和sheme,但不包括query_string的部分

    将所有参数(包括GET或POST的参数,但不包含签名字段)格式化为“key=value”格式,如“k1=v1”、“k2=v2”、“k3=v3”;

    将格式化好的参数键值对以字典序升序排列后,拼接在一起,如“k1=v1k2=v2k3=v3”,并将http method和url按顺序拼接在这个字符串前面;

    在拼接好的字符串末尾追加上应用的secret_key,并进行urlencode形成base_string;

    上述字符串的MD5值即为签名的值:

    sign=MD5(urlencode($http_method$url$k1=$v1$k2=$v2$k3=$v3$secret_key)); 

    详细请看:http://developer.baidu.com/wiki/index.php?title=%E5%8F%82%E6%95%B0%E7%AD%BE%E5%90%8D%E7%AE%97%E6%B3%95

    	/**
    	 * 签名生成算法
    	 * @param HashMap<String,String> params 请求参数集,所有参数必须已转换为字符串类型
    	 * @param String secret 签名密钥
    	 * @return 签名
    	 * @throws IOException
    	 */
    	public static String getSignature(HashMap<String,String> params, String secret) throws IOException
    	{
    		// 先将参数以其参数名的字典序升序进行排序
    		Map<String, String> sortedParams = new TreeMap<String, String>(params);
    		Set<Entry<String, String>> entrys = sortedParams.entrySet();
    	 
    		// 遍历排序后的字典,将所有参数按"key=value"格式拼接在一起
    		StringBuilder basestring = new StringBuilder();
    		for (Entry<String, String> param : entrys) {
    			basestring.append(param.getKey()).append("=").append(param.getValue());
    		}
    		basestring.append(secret);
    	 
    		// 使用MD5对待签名串求签
    		byte[] bytes = null;
    		try {
    			MessageDigest md5 = MessageDigest.getInstance("MD5");
    			bytes = md5.digest(basestring.toString().getBytes("UTF-8"));
    		} catch (GeneralSecurityException ex) {
    			throw new IOException(ex);
    		}
    	 
    		// 将MD5输出的二进制结果转换为小写的十六进制
    		StringBuilder sign = new StringBuilder();
    		for (int i = 0; i < bytes.length; i++) {
    			String hex = Integer.toHexString(bytes[i] & 0xFF);
    			if (hex.length() == 1) {
    				sign.append("0");
    			}
    			sign.append(hex);
    		}
    		return sign.toString();
    	}

    接下来拼接好符合我创建应用的各个参数如下:

    http[s]://channel.api.duapp.com/rest/2.0/channel/channel?method=push_msg&apikey=省略                   //apikey  

    &sign=省略    //

    &timestamp=12344543232     //就默认

    &expires=1238747373   //保持默认

    &v=1                             //保持默认

    &device_type=3                //3 Android设备

    &push_type=3     //3 所有人

    &message_type=1     //1 通知

    &messages="{"大碗干拌":"","欢迎访问大碗干拌的CSDN博客":"test"}"     //消息内容

    &msg_keys="testkey"    //使用一个不重复的字符串(唯一区别消息)

    可以看到参数中有一个apikey,好吧,先去创建一个移动应用。

    运行结果:


    到了这个时候好奇的朋友可能会问,这个难道就没有一个封装好的API供我们使用吗?看过我前面关于激光推送文章的朋友可能已经想到了,呵呵,下一篇我们再来看封装好的API,这个就没有这么麻烦了,哈哈大笑









  • 相关阅读:
    找细胞(题解)
    关于dfs
    奇怪的电梯(题解)
    信息解码(Message Decoding ACM/ICPC 1991)
    查找最大元素
    8皇后问题(dfs)
    如何利用dfs遍历树
    dfs(计算细胞数量)
    决策树减支问题(优化)dfs减支问题
    组合数问题
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6469196.html
Copyright © 2011-2022 走看看