前段时间搞推送来着,安卓方面用到了百度的推送服务,由于只是简单的用到安卓推送的通知功能,所以没用百度推荐的C# SDK,通过借鉴网上的各种资料和百度的API,费了老大劲终于折腾出来一段能用的代码(早知道这么纠结,直接用别人的了。。。强迫症伤不起啊)

2016-2-17在2.0基础上修改的3.0(百度巨坑,接口文档写的稀烂,文档上也不写明sign签名MD5需要小写,就为了这个问题我抓狂了3天)

最新3.0的

public class BaiduPush
{
private const string url = "http://api.tuisong.baidu.com/rest/3.0/push/single_device";
private const string apikey = "XXXXXXXXXXXXXXXXXX";
private const string secret_key = "XXXXXXXXXXXXXXXXXXXXXXXXXX"; /// <summary>
/// 只简单实现单个设备通知功能
/// </summary>
/// <param name="channel_id"></param>
/// <param name="msg"></param>
/// <param name="type"></param>
public static void Send(string channel_id, string msg, string type)
{
WebClient webClient = new WebClient();
webClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
webClient.Headers.Add("User-Agent", "BCCS_SDK/3.0 (Darwin; Darwin Kernel Version 14.0.0: Fri Sep 19 00:26:44 PDT 2014; root:xnu-2782.1.97~2/RELEASE_X86_64; x86_64) PHP/5.6.3 (Baidu Push Server SDK V3.0.0 and so on..) cli/Unknown ZEND/2.6.0");
try
{
byte[] response = webClient.UploadData(url, "POST", StructData(channel_id, msg, type));
var ss = Encoding.UTF8.GetString(response, 0, response.Length);
}
catch (WebException ex)
{
Stream stream = ex.Response.GetResponseStream();
byte[] bs = new byte[1024];
int index = 0;
int b;
while ((b = stream.ReadByte()) > 0)
{
bs[index++] = (byte)b;
}
stream.Close();
var ss = Encoding.UTF8.GetString(bs, 0, index);
}
}
/// <summary>
/// 构建Data
/// </summary>
/// <param name="token"></param>
/// <param name="msg"></param>
/// <param name="type"></param>
/// <returns></returns>
private static byte[] StructData(string channel_id, string msg, string type)
{
DateTime utcNow = DateTime.UtcNow;
DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0);
uint timestamp = (uint)(utcNow - epoch).TotalSeconds;
uint expires = (uint)(utcNow.AddDays(1) - epoch).TotalSeconds; //一天后过期 Dictionary<string, string> dic = new Dictionary<string, string>();
dic.Add("apikey", apikey);
dic.Add("timestamp", timestamp.ToString());
dic.Add("expires", expires.ToString());
dic.Add("device_type", "3"); //3:android 4:iOS dic.Add("channel_id", channel_id);
dic.Add("msg_type", "1"); //取值如下:0:消息;1:通知。默认为0
dic.Add("msg", "{\"title\":\"hello\",\"description\":\"" + msg + "\",\"custom_content\":{\"ClassName\":\"igs.android.healthsleep.MainActivity\",\"PushMessageType\":" + type + "}}"); dic.Add("sign", StructSign("POST", url, dic, secret_key)); StringBuilder sb = new StringBuilder();
foreach (var d in dic)
{
sb.Append(d.Key + "=" + d.Value + "&");
}
sb.Remove(sb.Length - 1, 1);
return Encoding.UTF8.GetBytes(sb.ToString());
}
/// <summary>
/// 构建Sign
/// </summary>
/// <param name="httpMethod"></param>
/// <param name="url"></param>
/// <param name="dic"></param>
/// <param name="secret_key"></param>
/// <returns></returns>
private static string StructSign(string httpMethod, string url, Dictionary<string, string> dic, string secret_key)
{
//按key正序
dic = dic.OrderBy(p => p.Key).ToDictionary(p => p.Key, p => p.Value);
StringBuilder sb = new StringBuilder();
//构建键值对
foreach (var d in dic)
{
sb.Append(d.Key + "=" + d.Value);
}
string sign = httpMethod + url + sb + secret_key;
//url编码
sign = sign.UrlEncode();
//将编码后替换的字符大写,这地方是个坑。。。文档里根本没说明
char[] cs = new char[sign.Length];
for (int i = 0; i < sign.Length; i++)
{
cs[i] = sign[i];
if (sign[i] == '%')
{
cs[++i] = Convert.ToChar(sign[i].ToString().ToUpper());
cs[++i] = Convert.ToChar(sign[i].ToString().ToUpper());
}
}
//MD5加密
return new string(cs).MD5().ToLower(); //巨坑,sign原来要小写,接口文档里根本就没有说明。。。
}
}
/// <summary>
/// 用到的扩展方法
/// </summary>
public static class ExtendMethod
{
/// <summary>
/// MD5加密
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string MD5(this string str)
{
byte[] bs = new MD5CryptoServiceProvider().ComputeHash(Encoding.UTF8.GetBytes(str));
return BitConverter.ToString(bs).Replace("-", "");
}
/// <summary>
/// url编码
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string UrlEncode(this string str)
{
str = System.Web.HttpUtility.UrlEncode(str, Encoding.UTF8);
/*
* 不知道为什么微软要把空格编码为+,浏览器不认识啊
* 只能在这里手动替换下了
* */
return str.Replace("+", "%20");
}
}

  

以前2.0的

/// <summary>
/// 百度推送
/// </summary>
public class BaiduPush
{
private const string method = "push_msg";
private const string url = "https://channel.api.duapp.com/rest/2.0/channel/channel";
private const string apikey = "xxxxxxxxxxxxxxxxx";
private const string secret_key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"; public static string Push(string user_id, string title, string description, string msg_keys)
{
DateTime utcNow = DateTime.UtcNow;
DateTime epoch = new DateTime(, , , , , );
uint timestamp = (uint)(utcNow - epoch).TotalSeconds;
uint expires = (uint)(utcNow.AddDays() - epoch).TotalSeconds; //一天后过期 Dictionary<string, string> dic = new Dictionary<string, string>();
dic.Add("method", method);
dic.Add("apikey", apikey);
dic.Add("timestamp", timestamp.ToString());
dic.Add("expires", expires.ToString());
dic.Add("push_type", ""); //单播
dic.Add("device_type", ""); //Andriod设备
dic.Add("user_id", user_id);
dic.Add("message_type", ""); //只发通知
dic.Add("messages", "{\"title\":\"" + title + "\",\"description\":\"" + description + "\"}");
dic.Add("msg_keys", msg_keys); //消息标识 相同消息标识的消息会自动覆盖。只支持android。
dic.Add("sign", StructSign("POST", url, dic, secret_key)); StringBuilder sb = new StringBuilder();
foreach (var d in dic)
{
sb.Append(d.Key + "=" + d.Value + "&");
}
sb.Remove(sb.Length - , );
byte[] data = Encoding.UTF8.GetBytes(sb.ToString()); WebClient webClient = new WebClient();
try
{
webClient.Headers.Add("Content-Type", "application/x-www-form-urlencoded");//采取POST方式必须加的header,如果改为GET方式的话就去掉这句话即可
byte[] response = webClient.UploadData(url, "POST", data);
return Encoding.UTF8.GetString(response);
}
catch (WebException ex)
{
Stream stream = ex.Response.GetResponseStream();
byte[] bs = new byte[];
int i = ;
int b;
while ((b = stream.ReadByte()) > )
{
bs[i++] = (byte)b;
}
stream.Close();
return Encoding.UTF8.GetString(bs, , i);
}
}
/// <summary>
/// 构建Sign
/// </summary>
/// <param name="httpMethod"></param>
/// <param name="url"></param>
/// <param name="dic"></param>
/// <param name="secret_key"></param>
/// <returns></returns>
private static string StructSign(string httpMethod, string url, Dictionary<string, string> dic, string secret_key)
{
//按key正序
dic = dic.OrderBy(p => p.Key).ToDictionary(p => p.Key, p => p.Value);
StringBuilder sb = new StringBuilder();
//构建键值对
foreach (var d in dic)
{
sb.Append(d.Key + "=" + d.Value);
}
string sign = httpMethod + url + sb + secret_key;
//url编码
sign = sign.UrlEncode();
//将编码后替换的字符大写,这地方是个坑。。。
char[] cs = new char[sign.Length];
for (int i = ; i < sign.Length; i++)
{
cs[i] = sign[i];
if (sign[i] == '%')
{
cs[++i] = Convert.ToChar(sign[i].ToString().ToUpper());
cs[++i] = Convert.ToChar(sign[i].ToString().ToUpper());
}
}
//MD5加密
return new string(cs).MD5();
}
}

外加两个扩展方法

System.Web.HttpUtility.UrlEncode需要添加引用System.Web (.net framework 4.0 client profile下面找不到System.Web请切换到.net framework 4.0)

/// <summary>
/// MD5加密
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string MD5(this string str)
{
byte[] bs = new MD5CryptoServiceProvider().ComputeHash(Encoding.UTF8.GetBytes(str));
return BitConverter.ToString(bs).Replace("-", "");
}
/// <summary>
/// url编码
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string UrlEncode(this string str)
{
return System.Web.HttpUtility.UrlEncode(str, Encoding.UTF8);
}

C# 简单的百度推送代码的更多相关文章

  1. iOS开发三步搞定百度推送

    iOS开发三步搞定百度推送   百度推送很简单,准备工作:在百度云推送平台注册应用,上传证书. 步骤一: 百度云推送平台 http://push.baidu.com/sdk/push_client_s ...

  2. iOS百度推送的基本使用

    一.iOS证书指导 在 iOS App 中加入消息推送功能时,必须要在 Apple 的开发者中心网站上申请推送证书,每一个 App 需要申请两个证书,一个在开发测试环境下使用,另一个用于上线到 App ...

  3. 百度推送-sitemap-使用playframework框架实现-java

    主动推送的目的是能够把我们高质量内容推送给百度,但是首先你得有一个属于你自己的网站,在百度站长进行验证通过之后,才有资格推送百度sitemap. 百度站长平台为未使用百度统计的站点提供三种验证方式:文 ...

  4. 使用git推送代码到开源中国以及IDEA环境下使用git

    使用git推送代码到开源中国以及IDEA环境下使用git 在学习Java的过程中我们会使用到git这个工具来将我们本周所编写的代码上传到开源中国进行代码托管,而在使用git的时候有很多的同学由于不会操 ...

  5. php 实时推送代码

    网站质量不错的网站可以在百度站长平台/数据提交/sitemap栏目下看到实时推送的功能, 目前这个工具是邀请开放, 百度的实时推送的api接口可以实时推送我们新发布的文章, 保证百度在第一时间收录. ...

  6. 用 Go 编写一个简单的 WebSocket 推送服务

    用 Go 编写一个简单的 WebSocket 推送服务 本文中代码可以在 github.com/alfred-zhong/wserver 获取. 背景 最近拿到需求要在网页上展示报警信息.以往报警信息 ...

  7. DT7.0/6.0最简单实现主动推送方法

    最近研究destoon内核开发,开发了一个大型的信息站点:http://www.xuetong365.com/  但是新站如何提高收录和排名呢?网上有很多主动提交的方法,今天我分享一个自己原创的超级简 ...

  8. 使用nginx代理gogs遇到推送代码错误的问题(RPC failed; HTTP 413 curl 22 The requested URL returned error: 413)

    前提 代码管理我是用Gogs.Git,前些阵子使用Nginx将git.balabiu.com反向代理到了Gogs的默认端口,其他二级域名准备做其他使用, 导致上报代码出现了错误. 问题 推送代码报错误 ...

  9. ios8中百度推送接收不到

    ios8中百度推送接收类型会有所改变: //消息推送注冊 if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) { ...

随机推荐

  1. MyBatis笔记一:GettingStart

    MyBatis笔记一:GettingStart 1.MyBatis优点 我们的工具和各种框架的作用就是为了我们操作数据库简洁,对于一些数据库的工具能帮我们少写一些处理异常等等的代码,但是他们并不是自动 ...

  2. 【记录】ajax跨域问题jsonp正确的使用方式

    最近遇到ajax请求跨域问题,解决方案用jsonp,现记录如下: //跨域请求jsonp封装 function doJsonPostCallBack(type, url, data,async, ca ...

  3. celery使用的小记录

    一篇还不错的入门说明: http://www.bjhee.com/celery.html, 官方文档: http://docs.jinkan.org/docs/celery/getting-start ...

  4. iptables 防火墙(上)

    iptables 防火墙(上) 1. 防火墙概述 1.1 概念与作用 网络中的防火墙是一种将内部网络和外部网络分开的方法,是一种隔离技术.防火墙在内网与外网通信时进行访问控制,依据所设置的规则对数据包 ...

  5. SharpZipLib 文件/文件夹 过滤

    这里就不说压缩/解压了.网上教程太多. 主要说一下,解压时,如何过滤某些文件/文件夹 参考地址:https://github.com/icsharpcode/SharpZipLib/wiki/Fast ...

  6. goto和函数调用

      goto: 函数调用: 作用域 label在函数内定义,所以函数内   跳转操作 无条件 调用时先保存现场,复制实际参数,然后才是跳转 生存期 由于不是左值,它没有生存期,仅在编译期有意义.   ...

  7. Python的历史及介绍

    Python的诞生 Python的创始人吉多·范罗苏姆(Guido van Rossum),在1989年12月的圣诞节期间,为了打发时间,决定开发一种新的脚本解释程序,作为ABC语言的继承. 现在,p ...

  8. js获取url参数值的几种方式

    一.原生js获取URL参数值: 比如当前URL为:http://localhost:8080/#/page2?id=100&name=guanxy <template> <d ...

  9. mongodb客户端操作常用命令(续)

    之前有写过一篇mongodb客户端的操作常用命令 ,今天接着来记录分享一些关于mongodb账户权限设置的命令操作 上期mongodb客户端的操作常用命令地址:https://www.cnblogs. ...

  10. Dart编程实例 - Dynamic 关键字

    Dart编程实例 - Dynamic 关键字 void main() { dynamic x = "tom"; print(x); } 本文转自:http://codingdict ...