信鴿推送官方sdk沒提供C#版的DEMO,考慮到應該有其他.NET的也會用到信鴿,下麵是我在使用信鴿過程中寫的demo。有什麼不對的地方,歡迎各位大牛指導。 ...
信鴿官方sdk沒提供C#版的DEMO,考慮到應該有其他.NET的也會用到信鴿,下麵是我在使用信鴿過程中寫的demo。有什麼不對的地方,歡迎各位大牛指導。
使用過程中主要是有2個問題:
1.參數組裝,本demo使用Dictionary進行組裝和排序;
2.生成 sign(簽名)
下文貼出單個設備推送的代碼(忽略大多數輔組實體的代碼,下麵會貼上源代碼)
1.Android 消息實體類 Message
public class Message { public Message() { this.title = ""; this.content = ""; this.sendTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); this.accept_time = new List<TimeInterval>(); this.multiPkg = 0; this.raw = ""; this.loopInterval = -1; this.loopTimes = -1; this.action = new ClickAction(); this.style = new Style(0); this.type = Message.TYPE_MESSAGE; } public bool isValid() { if (!string.IsNullOrWhiteSpace(raw)) { return true; } if (type < TYPE_NOTIFICATION || type > TYPE_MESSAGE) return false; if (multiPkg < 0 || multiPkg > 1) return false; if (type == TYPE_NOTIFICATION) { if (!style.isValid()) return false; if (!action.isValid()) return false; } if (expireTime < 0 || expireTime > 3 * 24 * 60 * 60) return false; try { DateTime.Parse(sendTime); } catch (Exception e) { return false; } foreach (var item in accept_time) { if (!item.isValid()) return false; } if (loopInterval > 0 && loopTimes > 0 && ((loopTimes - 1) * loopInterval + 1) > 15) { return false; } return true; } public string ToJosnByType() { if (type == TYPE_MESSAGE) { var obj = new { title = title, content = content, accept_time = accept_time.ToJson() }; return obj.ToJson(); } return this.ToJson(); } /// <summary> /// 1:通知 /// </summary> public static readonly int TYPE_NOTIFICATION = 1; /// <summary> /// 2:透傳消息 /// </summary> public static readonly int TYPE_MESSAGE = 2; public String title; public String content; public int expireTime; public String sendTime; private List<TimeInterval> accept_time; public int type; public int multiPkg; private Style style; private ClickAction action; /// <summary> /// 自定義參數,所有的系統app操作參數放這裡 /// </summary> public string custom_content; public String raw; public int loopInterval; public int loopTimes; }View Code
2.組裝參數函數
/// <summary> /// Android單個設備 推送信息 /// </summary> /// <param name="deviceToken">針對某一設備推送,token是設備的唯一識別 ID</param> /// <param name="message"></param> /// <returns></returns> public string pushSingleDevice(String deviceToken, Message message) { if (!ValidateMessageType(message)) { return ""; } if (!message.isValid()) { return ""; } Dictionary<String, Object> dic = new Dictionary<String, Object>(); dic.Add("access_id", this.m_accessId); dic.Add("expire_time", message.expireTime); dic.Add("send_time", message.sendTime); dic.Add("multi_pkg", message.multiPkg); dic.Add("device_token", deviceToken); dic.Add("message_type", message.type); dic.Add("message", message.ToJson()); dic.Add("timestamp", DateTime.Now.DateTimeToUTCTicks()); return CallRestful(XinGeAPIUrl.RESTAPI_PUSHSINGLEDEVICE, dic); }View Code
3.生成簽名
/// <summary> /// 生成 sign(簽名) /// </summary> /// <param name="method"></param> /// <param name="url"></param> /// <param name="dic"></param> /// <returns></returns> protected String GenerateSign(String method, String url, Dictionary<String, Object> dic) { var str = method; Uri address = new Uri(url); str += address.Host; str += address.AbsolutePath; var dic2 = dic.OrderBy(d => d.Key); foreach (var item in dic2) { str += (item.Key + "=" + (item.Value == null ? "" : item.Value.ToString())); } str += this.m_secretKey; var s_byte = Encoding.UTF8.GetBytes(str); MD5 md5Hasher = MD5.Create(); byte[] data = md5Hasher.ComputeHash(s_byte); StringBuilder sBuilder = new StringBuilder(); for (int i = 0; i < data.Length; i++) { sBuilder.Append(data[i].ToString("x2")); } return sBuilder.ToString(); }View Code
4.生成請求的地址和調用請求
/// <summary> /// 生成請求的地址和調用請求 /// </summary> /// <param name="url"></param> /// <param name="dic"></param> /// <returns></returns> protected string CallRestful(String url, Dictionary<String, Object> dic) { String sign = GenerateSign("POST", url, dic); if (string.IsNullOrWhiteSpace(sign)) { return (new { ret_code = -1, err_msg = "generateSign error" }).ToJson(); } dic.Add("sign", sign); try { var param = ""; foreach (var item in dic) { var key = item.Key; var value = HttpUtility.UrlEncode(item.Value == null ? "" : item.Value.ToString(), Encoding.UTF8); param = string.IsNullOrWhiteSpace(param) ? string.Format("{0}={1}", key, value) : string.Format("{0}&{1}={2}", param, key, value); } return Request(url, "POST", param); } catch (Exception e) { return e.Message; } }View Code
5.輔助校驗方法
protected bool ValidateMessageType(Message message) { if (this.m_accessId < XinGeAPIUrl.IOS_MIN_ID) return true; else return false; }View Code
6.Http請求
public string Request(string _address, string method = "GET", string jsonData = null, int timeOut = 5) { string resultJson = string.Empty; if (string.IsNullOrEmpty(_address)) return resultJson; try { Uri address = new Uri(_address); // 創建網路請求 HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest; //System.Net.ServicePointManager.DefaultConnectionLimit = 50; // 構建Head request.Method = method; request.KeepAlive = false; Encoding myEncoding = Encoding.GetEncoding("utf-8"); if (!string.IsNullOrWhiteSpace(jsonData)) { byte[] bytes = Encoding.UTF8.GetBytes(jsonData); using (Stream reqStream = request.GetRequestStream()) { reqStream.Write(bytes, 0, bytes.Length); reqStream.Close(); } } request.Timeout = timeOut * 1000; request.ContentType = "application/x-www-form-urlencoded"; using (HttpWebResponse response = request.GetResponse() as HttpWebResponse) { StreamReader reader = new StreamReader(response.GetResponseStream()); string responseStr = reader.ReadToEnd(); if (responseStr != null && responseStr.Length > 0) { resultJson = responseStr; } } } catch (Exception ex) { resultJson = ex.Message; } return resultJson; }View Code
7.發送一個推送
public bool pushSingleDevice(String deviceToken, string account, string title, string content, Dictionary<string, object> custom, out string returnStr) { content = content.Replace("\r", "").Replace("\n", ""); Message android = new Message(); android.title = title; android.content = content; android.custom_content = custom.ToJson(); returnStr = pushSingleDevice(deviceToken, android); return true; }View Code
註意:IOS需要區分開發和正式環境