Baidu_Helper.cs 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Web;
  6. using System.Net;
  7. using System.IO;
  8. using System.Net.Security;
  9. using System.Security.Cryptography.X509Certificates;
  10. using System.Net.Http;
  11. using System.Net.Http.Headers;
  12. using System.Threading.Tasks;
  13. using Newtonsoft.Json;
  14. namespace CommLib.BdPush
  15. {
  16. /// <summary>
  17. /// 作者:冼树华
  18. /// QQ:56472465
  19. /// 日期:20150-04-29
  20. /// 功能:百度推送帮助类
  21. /// </summary>
  22. public class Baidu_Helper
  23. {
  24. #region 枚举参数
  25. /// <summary>
  26. /// 设备类型
  27. /// </summary>
  28. public enum Device_Type : uint { Android = 3, IOS = 4 };
  29. /// <summary>
  30. /// 推送类型
  31. /// </summary>
  32. public enum Push_Type : uint { Signle = 1, Multiple = 2, All = 3 };
  33. /// <summary>
  34. /// 消息类型
  35. /// </summary>
  36. public enum Message_Type : uint { Message = 0, Notice = 1 }
  37. /// <summary>
  38. /// 部署状态
  39. /// </summary>
  40. public enum Deploy_Status : uint { Develope = 1, Product = 2 }
  41. //0:tag组播; 1:广播; 2:批量单播; 3:标签组合; 4:精准推送; 5:LBS推送; 6:系统保留; 7:单播;
  42. public enum Query_Type : uint
  43. {
  44. TagPush = 0, Push = 1, BatchPush = 2, TagsPush = 3,
  45. PrecisionPush = 4, LBSPush = 5, SysKeep = 6, SignalPush = 7
  46. }
  47. #endregion
  48. #region http传输方式
  49. public static readonly string HTTP_POST = "post"; //post传输
  50. public static readonly string HTTP_GET = "get"; //get传输
  51. #endregion
  52. #region 相关URL的方法参数
  53. public static readonly string PUSH_SIGNLE_DEVICE = "push/single_device"; //推送消息到单台设备
  54. public static readonly string PUSH_ALL = "push/all"; //推送广播消息
  55. public static readonly string PUSH_TAGS = "push/tags"; //推送组播消息
  56. public static readonly string PUSH_BATCH_DEVICE = "push/batch_device"; //推送消息到给定的一组设备(批量单播)
  57. public static readonly string REPORT_QUERY_MSG_STATUS = "report/query_msg_status"; //查询消息的发送状态
  58. public static readonly string REPORT_QUERY_TIMER_RECORDS = "report/query_timer_records"; //查询定时消息的发送记录
  59. public static readonly string REPORT_QUERY_TOPIC_RECORDS = "report/query_topic_records"; //查询指定分类主题的发送记录
  60. public static readonly string APP_QUERY_TAGS = "app/query_tags"; //查询标签组列表
  61. public static readonly string APP_CREATE_TAG = "app/create_tag"; //创建标签组
  62. public static readonly string APP_DEL_TAG = "app/del_tag"; //删除标签组
  63. public static readonly string TAG_ADD_DEVICES = "tag/add_devices"; //添加设备到标签组
  64. public static readonly string TAG_DEL_DEVICES = "tag/del_devices"; //将设备从标签组中移除
  65. public static readonly string TAG_DEVICE_NUM = "tag/device_num"; //查询标签组设备数量
  66. public static readonly string TIMER_QUERY_LIST = "timer/query_list"; //查询定时任务列表
  67. public static readonly string TIMER_CANCEL = "timer/cancel"; //取消定时任务
  68. public static readonly string TOPIC_QUERY_LIST = "topic/query_list"; //查询分类主题列表
  69. public static readonly string REPORT_STATISTIC_MSG = "report/statistic_msg"; //当前应用的消息统计信息
  70. public static readonly string REPORT_STATISTIC_DEVICE = "report/statistic_device"; //当前应用的设备统计信息
  71. public static readonly string REPORT_STATISTIC_TOPIC = "report/statistic_topic"; //查询分类主题统计信息
  72. #endregion
  73. #region 获取签名
  74. private static string CreateSign(string httpMethod, string url, string secretKey, Baidu_Mod mod)
  75. {
  76. string sign = "";
  77. if (mod != null)
  78. {
  79. Dictionary<string, string> dic = new Dictionary<string, string>();
  80. //将键值对按照key的升级排列
  81. var props = mod.GetType().GetProperties().OrderBy(p => p.Name);
  82. string pValue = "";
  83. foreach (var p in props)
  84. {
  85. if (p.GetValue(mod, null) != null)
  86. {
  87. pValue = p.GetValue(mod, null).ToString();
  88. if (pValue != "0")//unint为0是不添加,如广播消息的预定发送时间
  89. dic.Add(p.Name, p.GetValue(mod, null).ToString());
  90. }
  91. }
  92. //生成sign时,不能包含sign标签,所有移除
  93. dic.Remove("sign");
  94. var preData = new StringBuilder();
  95. foreach (var l in dic)
  96. {
  97. preData.Append(l.Key);
  98. preData.Append("=");
  99. preData.Append(l.Value);
  100. }
  101. //按要求拼接字符串,并urlencode编码
  102. var str = HttpUtility.UrlEncode(httpMethod.ToUpper() + url + preData.ToString() + secretKey);
  103. var strSignUpper = new StringBuilder();
  104. int perIndex = 0;
  105. for (int i = 0; i < str.Length; i++)
  106. {
  107. var c = str[i].ToString();
  108. if (str[i] == '%')
  109. {
  110. perIndex = i;
  111. }
  112. if (i - perIndex == 1 || i - perIndex == 2)
  113. {
  114. c = c.ToUpper();
  115. }
  116. strSignUpper.Append(c);
  117. }
  118. // 获取sign的值
  119. sign = Tool.Md5Hash(strSignUpper.ToString()).ToLower();
  120. }
  121. return sign;
  122. }
  123. #endregion
  124. #region 创建参数集合
  125. private static Dictionary<string, string> GetParamerCollection(Baidu_Mod mod, string sign)
  126. {
  127. Dictionary<string, string> paramerCollection = new Dictionary<string, string>();
  128. var props = mod.GetType().GetProperties();
  129. string pValue = "";
  130. foreach (var p in props)
  131. {
  132. if (p.GetValue(mod, null) != null)
  133. {
  134. pValue = p.GetValue(mod, null).ToString();
  135. if (pValue != "0")//unint为0是不添加,如广播消息的预定发送时间
  136. paramerCollection.Add(p.Name, p.GetValue(mod, null).ToString());
  137. }
  138. }
  139. paramerCollection.Add("sign", sign);
  140. return paramerCollection;
  141. }
  142. #endregion
  143. #region 发送消息到百度
  144. public static async Task<string> SendBaidu(string httpMethod, string url, string secretKey, Baidu_Mod mod)
  145. {
  146. //获取签名
  147. string strSign = CreateSign(httpMethod, url, secretKey, mod);
  148. string responseContent = ""; //返回字符串
  149. //使用本机代理fiddler进行测试
  150. //var handler = new HttpClientHandler()
  151. //{
  152. // Proxy = new WebProxy("http://127.0.0.1:8888", false, new string[] { }),
  153. // UseProxy = true
  154. //};
  155. using (var client = new HttpClient())
  156. {
  157. client.BaseAddress = new Uri(url); //设置WebAPI的地址+类+方法
  158. client.DefaultRequestHeaders.Accept.Clear(); //清空缓存
  159. client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"){CharSet="utf-8"}); //返回值为json和utf-8编码
  160. //响应消息
  161. HttpResponseMessage response = null;
  162. //判断使用不同的HttpMethod,生成不同的参数,获取相关返回数据
  163. if (HttpMethod.Get.Method.ToLower().Equals(httpMethod.ToLower())) //get方法(暂不提供)
  164. {
  165. }
  166. else if (HttpMethod.Post.Method.ToLower().Equals(httpMethod.ToLower())) //post方法
  167. {
  168. //生成post的参数,并且设置charset为utf-8
  169. Dictionary<string, string> requestDictionary = GetParamerCollection(mod, strSign);
  170. var contents = new FormUrlEncodedContent(requestDictionary);
  171. contents.Headers.ContentType.CharSet = "utf-8";
  172. await contents.LoadIntoBufferAsync();
  173. response = await client.PostAsync(url, contents);
  174. }
  175. //返回值
  176. responseContent = await response.Content.ReadAsStringAsync();
  177. }// http完结
  178. return responseContent;
  179. }
  180. #endregion
  181. #region https证书验证
  182. //
  183. private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
  184. {
  185. return true; //总是接受
  186. }
  187. #endregion
  188. }
  189. }