C# 简单的百度推送代码

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

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

最新3.0的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
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(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("method", method);
            dic.Add("apikey", apikey);
            dic.Add("timestamp", timestamp.ToString());
            dic.Add("expires", expires.ToString());
            dic.Add("push_type", "1"); //单播
            dic.Add("device_type", "3"); //Andriod设备 
            dic.Add("user_id", user_id);
            dic.Add("message_type", "1"); //只发通知
            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 - 1, 1);
            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[256];
                int i = 0;
                int b;
                while ((b = stream.ReadByte()) > 0)
                {
                    bs[i++] = (byte)b;
                }
                stream.Close();
                return Encoding.UTF8.GetString(bs, 0, 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 = 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();
        }
    }
复制代码

外加两个扩展方法  

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);
        }
复制代码

 

posted @   WmW  阅读(976)  评论(3编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示