C# 簡單的百度推送代碼

前段時間搞推送來着,安卓方面用到了百度的推送服務,因爲只是簡單的用到安卓推送的通知功能,因此沒用百度推薦的C# SDK,經過借鑑網上的各類資料和百度的API,費了老大勁終於折騰出來一段能用的代碼(早知道這麼糾結,直接用別人的了。。。強迫症傷不起啊)android

2016-2-17在2.0基礎上修改的3.0(百度巨坑,接口文檔寫的稀爛,文檔上也不寫明sign簽名MD5須要小寫,就爲了這個問題我抓狂了3天)web

最新3.0的api

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();
        }
    }

外加兩個擴展方法  app

System.Web.HttpUtility.UrlEncode須要添加引用System.Web (.net framework 4.0 client profile下面找不到System.Web請切換到.net framework 4.0)ide

/// <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);
        }
相關文章
相關標籤/搜索