這次公司要我們做一個功能,就是當(dāng)用戶成功注冊以后,他登錄以后要收到消息,當(dāng)然這個消息是安裝了我們的手機(jī)APP應(yīng)用的手機(jī)咯。 極光推送的網(wǎng)站的網(wǎng)址是:https://www./ 極光推送的官方API以及幫助文檔都在這里:http://docs./display/dev/Index 其中服務(wù)端的接口以及示例代碼都在這里:http://docs./display/dev/Server-SDKs 大家有興趣的可以看看,因?yàn)檫@次我做的不是客戶端APP,所以一筆帶過啦,就跟大家介紹一下C#端的吧。 首先我們下載一下極光推送的C#例子吧,如下圖。
然后例子里面有詳細(xì)的介紹,注釋什么的。 極光推送的NET.FRAMEWORK的版本號是4.0的,所以如果我們的網(wǎng)站如果是2.0的,那么就要把極光推送的代碼集成到WebService里面,然后從要用的時候直接調(diào)用這個WebService就行了。 下面是例子的源碼: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Collections; using cn.jpush.api; using cn.jpush.api.push; using cn.jpush.api.report; using cn.jpush.api.common; using cn.jpush.api.util; namespace JpushApiClientExample { class JPushApiExample { public class ExtralClass { public String sound = "ssss"; public String menu="button"; } static void Main(string[] args) { Console.WriteLine("************"); Console.WriteLine("*****開始發(fā)送******"); //String result; String app_key = "_"; String master_secret = "_"; //int sendno = 9; HashSet<DeviceEnum> set = new HashSet<DeviceEnum>(); set.Add(DeviceEnum.Android); set.Add(DeviceEnum.IOS); JPushClient client = new JPushClient(app_key, master_secret, 0, set, true); MessageResult result = null; NotificationParams notifyParams = new NotificationParams(); CustomMessageParams customParams = new CustomMessageParams(); //notifyParams. //傳入json字符串 String extras = null; extras = "{\"ios\":{\"badge\":88, \"sound\":\"happy\"}}"; //extras中有中文請用HttpUtility.UrlEncode編碼 //System.Web.HttpUtility.UrlEncode(notificationContent, Encoding.UTF8); Console.WriteLine("*****發(fā)送帶tag通知******"); /** *發(fā)送類型 *APP_KEY 通知 *TAG TAG *ALIAS ALIAS *REGISTRATION_ID REGISTRATION_ID */ notifyParams.ReceiverType = ReceiverTypeEnum.APP_KEY; notifyParams.SendNo = 256; //notifyParams.OverrideMsgId = "1"; result = client.sendNotification("酷派tag111111", notifyParams, extras); Console.WriteLine("sendNotification by tag:**返回狀態(tài):" + result.getErrorCode().ToString() + " **返回信息:" + result.getErrorMessage() + " **Send No.:" + result.getSendNo() + " msg_id:" + result.getMessageId() + " 頻率次數(shù):" + result.getRateLimitQuota() + " 可用頻率:" + result.getRateLimitRemaining() + " 重置時間:" + result.getRateLimitReset()); Console.WriteLine("*****發(fā)送帶tag消息******"); //customParams.addPlatform(DeviceEnum.Android); customParams.ReceiverType = ReceiverTypeEnum.TAG; customParams.ReceiverValue = "tag_api"; customParams.SendNo = 256; result = client.sendCustomMessage("send custom mess by tag", "tag notify content", customParams, extras); Console.WriteLine("sendCustomMessage:**返回狀態(tài):" + result.getErrorCode().ToString() + " **返回信息:" + result.getErrorMessage() + " **Send No.:" + result.getSendNo() + " msg_id:" + result.getMessageId() + " 頻率次數(shù):" + result.getRateLimitQuota() + " 可用頻率:" + result.getRateLimitRemaining() + " 重置時間:" + result.getRateLimitReset()); Console.WriteLine(); String msg_ids = "1613113584,1229760629,1174658841,1174658641"; ReceivedResult receivedResult = client.getReceivedApi(msg_ids); Console.WriteLine("Report Result:"); foreach(ReceivedResult.Received re in receivedResult.ReceivedList) { Console.WriteLine("getReceivedApi************msgid=" + re.msg_id+ " ***andriod received="+re.android_received+" ***ios received="+re.ios_apns_sent); } Console.WriteLine(); } public class IOSExtras { public int badge = 888; public String sound = "happy"; } } }View Code 然后我們還是來結(jié)合例子一步一步走吧。 首先是發(fā)送通知: Console.WriteLine("************"); Console.WriteLine("*****開始發(fā)送******"); //String result; String app_key = "_"; String master_secret = "_"; //int sendno = 9; HashSet<DeviceEnum> set = new HashSet<DeviceEnum>(); set.Add(DeviceEnum.Android); set.Add(DeviceEnum.IOS); JPushClient client = new JPushClient(app_key, master_secret, 0, set, true); MessageResult result = null; NotificationParams notifyParams = new NotificationParams(); CustomMessageParams customParams = new CustomMessageParams(); //notifyParams. //傳入json字符串 String extras = null; extras = "{\"ios\":{\"badge\":88, \"sound\":\"happy\"}}"; //extras中有中文請用HttpUtility.UrlEncode編碼 //System.Web.HttpUtility.UrlEncode(notificationContent, Encoding.UTF8); Console.WriteLine("*****發(fā)送帶tag通知******"); /** *發(fā)送類型 *APP_KEY 通知 *TAG TAG *ALIAS ALIAS *REGISTRATION_ID REGISTRATION_ID */ notifyParams.ReceiverType = ReceiverTypeEnum.APP_KEY; notifyParams.SendNo = 256; //notifyParams.OverrideMsgId = "1"; result = client.sendNotification("酷派tag111111", notifyParams, extras); Console.WriteLine("sendNotification by tag:**返回狀態(tài):" + result.getErrorCode().ToString() + " **返回信息:" + result.getErrorMessage() + " **Send No.:" + result.getSendNo() + " msg_id:" + result.getMessageId() + " 頻率次數(shù):" + result.getRateLimitQuota() + " 可用頻率:" + result.getRateLimitRemaining() + " 重置時間:" + result.getRateLimitReset()); 這里我們需要先了解幾個概念。
這個是我自己總結(jié)的,無非就是我們在極光推送ISP里的一個相當(dāng)于對于APP應(yīng)用的一個唯一進(jìn)入憑證。 極光推送C#版本的SDK目前支持Android和IOS系統(tǒng),因?yàn)樯厦娴拇a是發(fā)送通知,而通知應(yīng)該是對所有安裝了APP的人開放,所以應(yīng)該選擇APP_KEY。 大家是不是對JpushClient這個類有些疑惑呢,下面就帶大家來解析這個類。 public class JPushClient { private PushClient _pushClient; /// <summary> /// 帶兩個參數(shù)的構(gòu)造函數(shù),該狀態(tài)下,ApnsProduction默認(rèn)為true /// </summary> /// <param name="app_key">Portal上產(chǎn)生的app_key</param> /// <param name="masterSecret">你的API MasterSecret</param> public JPushClient(String app_key, String masterSecret) { HashSet<DeviceEnum> devices = new HashSet<DeviceEnum>(); devices.Add(DeviceEnum.IOS); devices.Add(DeviceEnum.Android); _pushClient = new PushClient(masterSecret, app_key, MessageParams.NO_TIME_TO_LIVE, null, true); _reportClient = new ReportClient(app_key, masterSecret); } /// <summary> /// 發(fā)送通知 /// </summary> /// <param name="notificationContent">通知內(nèi)容</param> /// <param name="notifyParams"></param> /// <param name="extras"></param> /// <returns></returns> public MessageResult sendNotification(String notificationContent, NotificationParams notifyParams, String extras) { return _pushClient.sendNotification(notificationContent, notifyParams, extras); } } 看來上面其實(shí)就是帶入了幾個參數(shù),其核心是PushClient,磨刀不誤砍柴工,我們來看看PushClient這個類。 internal class PushClient:BaseHttpClient { private const String HOST_NAME_SSL = "https://api."; private const String HOST_NAME = "http://api.:8800"; private const String PUSH_PATH = "/v2/push"; private String appKey; private String masterSecret; private bool enableSSL = false; private long timeToLive; private bool apnsProduction = false; private HashSet<DeviceEnum> devices = new HashSet<DeviceEnum>(); public MessageResult sendNotification(String notificationContent, NotificationParams notParams, String extras) { if ( !string.IsNullOrEmpty(extras) ) { notParams.NotyfyMsgContent.n_extras = extras; } notParams.NotyfyMsgContent.n_content = System.Web.HttpUtility.UrlEncode(notificationContent, Encoding.UTF8); //notParams.NotyfyMsgContent.n_content = notificationContent; return sendMessage(notParams, MsgTypeEnum.NOTIFICATIFY); } private MessageResult sendPush(MessageParams msgParams, MsgTypeEnum msgType) { String url = enableSSL ? HOST_NAME_SSL : HOST_NAME; url += PUSH_PATH; String pamrams = prase(msgParams, msgType); //Console.WriteLine("begin post"); ResponseResult result = sendPost(url, null, pamrams); //Console.WriteLine("end post"); MessageResult messResult = new MessageResult(); if (result.responseCode == System.Net.HttpStatusCode.OK) { //Console.WriteLine("responseContent===" + result.responseContent); messResult = (MessageResult)JsonTool.JsonToObject(result.responseContent, messResult); String content = result.responseContent; } messResult.ResponseResult = result; return messResult; } } 從上面看來,這個地方有2個重點(diǎn),一個是極光推送給我們的接口地址,這個非常重要, 另一個就是SendPush方法,下面的Parse方法轉(zhuǎn)換成極光推送認(rèn)識的字符串也是相當(dāng)?shù)闹匾摹?/p> private String prase(MessageParams message, MsgTypeEnum msgType) { StringBuilder sb = new StringBuilder(); sb.Append(message.SendNo).Append((int)message.ReceiverType).Append(message.ReceiverValue).Append(message.MasterSecret); String verificationCode = sb.ToString(); //Console.WriteLine(verificationCode); verificationCode = Md5.getMD5Hash(verificationCode); sb.Clear(); message.setMsgContent(); String receiverVallue = System.Web.HttpUtility.UrlEncode(message.ReceiverValue, Encoding.UTF8); sb.Append("sendno=").Append(message.SendNo).Append("&app_key=").Append(message.AppKey).Append("&receiver_type=").Append((int)message.ReceiverType) .Append("&receiver_value=").Append(receiverVallue).Append("&verification_code=").Append(verificationCode) .Append("&msg_type=").Append((int)msgType).Append("&msg_content=").Append(message.MsgContent).Append("&platform=").Append(message.getPlatform()) .Append("&apns_production=").Append(message.ApnsProduction); if(message.TimeToLive >= 0) { sb.Append("&time_to_live=").Append(message.TimeToLive); } if(message.OverrideMsgId != null) { sb.Append("&override_msg_id=").Append(message.OverrideMsgId); } Console.WriteLine(sb.ToString()); //Debug.Print(sb.ToString()); return sb.ToString(); } } 上面的調(diào)用方法其實(shí)極光推送里面也寫到了:http://docs./display/dev/Push+API+v2 其實(shí)很明白了,上面的就是我們一開始帶進(jìn)來的參數(shù)了,至于msgid,我猜想應(yīng)該是極光推送給我們自動生成的一個自增長的ID,當(dāng)然這個肯定是服務(wù)端生成的。 總結(jié)一下上面的一切的一切,其實(shí)無非就是方法之間的嵌套調(diào)用,真正的重點(diǎn)是調(diào)用到的最終的極光推送的URL的那個接口。相當(dāng)于我們只是傳參數(shù)吧。 不過我猜想應(yīng)該是極光推送的保密性,不然哪里會這么調(diào)用呢,直接傳個URL不就得了。偷笑~~ 下面我們再來討論一下給單個用戶推消息,比如:有一個注冊用戶,他的文章需要審核才能發(fā)布,然后管理員審核了他的文章,當(dāng)管理員審核通過的那么一瞬間,就應(yīng)該給這個安裝了APP的用戶發(fā)送一條消息,提示這個用戶應(yīng)該取發(fā)布文章了。這個就是向單個人去推的思路。 因?yàn)楣具@次的項(xiàng)目只用到了ALIAS(別名),就想當(dāng)于每個在手機(jī)上登錄的用戶,都邦定了一個別名,這個別名是唯一的,但是卻是區(qū)別于用戶名的,只要這個用戶邦定了這個別名,即使他的APP保持了登錄狀態(tài)(沒有注銷),那么他在任何時刻都可以接受到服務(wù)端SDK給這個用戶推送到的消息。如下圖。
這個別名是怎么產(chǎn)生的呢,因?yàn)槲以趙ebservice里面給了手機(jī)端一個登錄接口,這個登錄接口的形參里有別名,當(dāng)然了,我是通過用戶名去尋找別名了,下面是代碼 ,最后返回的是一個JSON的字符串 //用戶登錄 [WebMethod(Description = "用戶登錄,帶入?yún)?shù),用戶名,密碼以及數(shù)據(jù)庫的類型", EnableSession = true)] public string LoginUser(string username, string password,string alias) { JavaScriptSerializer ser = new JavaScriptSerializer(); SysBaseTag sys = new SysBaseTag(); sys.data = new List<object>(); try { //輸入查詢用戶的SQL,查詢2張表,一張用戶表,一張用戶詳細(xì)信息表。 string sql = "select a.*,b.* from t_sys_user a,t_sys_userinfo b where a.id='" + username + "' and a.password='" + password + "' and a.id=b.userid"; //查詢出結(jié)果 DataSet dbSet = DBHelperSQL.Query(sql, DBHelperSQL.GetDBString(), 2); if (dbSet != null && dbSet.Tables[0].Rows.Count > 0) { sys.message = "成功"; sys.result = true; Users userInfo = new Users(); foreach (DataRow Row in dbSet.Tables[0].Rows) { userInfo.ID = Row["ID"].ToString(); userInfo.Phone = Row["Phone"].ToString(); userInfo.Name = Row["name"].ToString(); userInfo.Email = Row["email"].ToString(); userInfo.QQ = Row["qq"].ToString(); userInfo.CompanyName = Row["companyname"].ToString(); userInfo.ComapnyType = Row["companytype"].ToString(); userInfo.CompanyAddress = Row["companyaddress"].ToString(); userInfo.Website = Row["website"].ToString(); userInfo.Introduce = Row["introduce"].ToString(); userInfo.Products = Row["products"].ToString(); userInfo.Reward = Row["reward"].ToString(); } sys.data.Add(userInfo); sys.count = 1; //臨時:插入別名 string sql_ins = "update t_sys_user set alias='" + alias + "' where id='" + username + "'"; int a=DBHelperSQL.ExecuteSQL(sql_ins,DBHelperSQL.GetDBString(),2); } else { sys.message = "失敗"; sys.result = false; sys.count = 0; } } catch (System.Exception e) { sys.message = e.Message; sys.result = false; sys.count = 0; } return ser.Serialize(sys); } 因?yàn)榭蛻粜枰?,我還做了一個表,專門存放手機(jī)消息的發(fā)送記錄,如果成功推送消息,那么就往這張表里插入一條記錄。 下面是JSON的示例,大家看看就好。
總之大家要明白,ALIAS是唯一的,不同于用戶名的,我們判斷的是這個人對應(yīng)的手機(jī)APP的ALIAS(唯一性),而不是關(guān)心她的用戶名。 基本上原理就這樣,然后的話我們需要建立一個WEBSERVICE,ASMX文件,然后把這個ASMX文件部署到網(wǎng)上去。 比如我們調(diào)用這個WebService的地址是http:///test.asmx,基本上就這個原理了。通過后臺傳參數(shù)給WEBSERVICE。 //發(fā)布文章的時候同時發(fā)送短信。 public void PublishToMobile(string []ids) { cs.Common.Web.BasePage bp = new cs.Common.Web.BasePage(); string ids_=""; //最終得到的字符串 for (int i = 0; i < ids.Length; i++) { ids_ += ",'" + ids[i]+"'"; } ids_ = ids_.Substring(1); DataSet set = bp.DataManager.Fill("select * from cms_core_content where id in(" + ids_ + ")"); string title = ""; //標(biāo)題 string content = ""; //內(nèi)容 string publishDate = ""; //發(fā)布時間 foreach (DataRow Row in set.Tables[0].Rows) { title = Row["title"].ToString(); content = Row["Text"].ToString(); publishDate = Row["publishdate"].ToString(); string wsUrl = BL.AppContext.AppSettings["MobileWs"]; string rs = (string)BL.WebHelper.InvokeWebService(wsUrl, "GetMsg_ArticlePublish", new object[] { publishDate, title, content }); } 上面的是一段示例代碼,其中的InvokeWebService方法就是調(diào)用Webservie的方法了,第一參數(shù)是調(diào)用的URL,第二個是方法名,第三個是參數(shù)。 基本上好像沒什么說的了吧,反正一個是群發(fā),一個是向某一個用戶發(fā),而用戶因?yàn)榘疃藙e名,所以可以通過這個別名向指定的用戶進(jìn)行發(fā)送消息, 下一次有空的話把微信那一塊的說一下,就是微信C#入門啦。 有什么問題還請大家多多切磋。 |
|