• C# 简单的百度推送代码


    前段时间搞推送来着,安卓方面用到了百度的推送服务,由于只是简单的用到安卓推送的通知功能,所以没用百度推荐的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(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);
            }
  • 相关阅读:
    【已解决】Android ADT中增大AVD内存后无法启动:emulator failed to allocate memory
    XE10 塔建 Android 开发环境 (已测试通过)
    Erstudio8.0怎么用?Erstudio8.0汉化版详细使用教程
    Excel 信息对比_数组版
    百万级数据查询优化(数据库)
    sql查询重复记录、删除重复记录方法大全
    JS和JSON的区别
    JS中字符串的true转化为boolean类型的true
    关于HTTP协议,一篇就够了
    关于JS的prototype
  • 原文地址:https://www.cnblogs.com/luludongxu/p/4476318.html
Copyright © 2020-2023  润新知