最近做公司的一個項目.一旦數據庫插入新的消息,就要通知服務器,將這些新的消息推送給蘋果客戶端,以前我們的項目中有人做過這個功能,無奈做的有點復雜,而且代碼沒注釋,我壓根就沒看懂.所以自己打算重新搞一個.
小小研究了一個,找到PushSharp這個類庫,(超級強大),然后用了下感覺很不錯,推薦給大家,為大家介紹下.
一.首先來了解下這幾個類庫
引用PushSharp 的幾個類庫
PushSharp.Core:核心庫必須引用
PushSharp.Apple:向蘋果推送的類庫
PushSharp.Android:C2DM及GCM,用於Android設備
PushSharp.Windows:用於Windows 8
PushSharp.WindowsPhone:用於WP設備
PushSharp.Amazon.Adm:用於Amazon的設備
PushSharp.Blackberry:用於黑莓設備
PushSharp.Google.Chrome:用於Chrome
這些類庫按照自己的項目要求使用即可
二.簡單的示例代碼
注意,如果你需要給蘋果推送 你首先要給你的APP去注冊一個證書,然后在你的APP中寫一些代碼,來接受推送.
//創建一個推送對象
private PushBroker push=new PushBroker();
//關聯推送狀態事件
push.OnNotificationSent += NotificationSent;
push.OnChannelException += ChannelException;
push.OnServiceException += ServiceException;
push.OnNotificationFailed += NotificationFailed;
push.OnDeviceSubscriptionExpired += DeviceSubscriptionExpired;
push.OnDeviceSubscriptionChanged += DeviceSubscriptionChanged;
push.OnChannelCreated += ChannelCreated;
push.OnChannelDestroyed += ChannelDestroyed;
var appleCert = File.ReadAllBytes("證書路徑");//將證書流式讀取
push.RegisterAppleService(new ApplePushChannelSettings(appleCert, "證書密碼"));//注冊推送通道
push.QueueNotification(new AppleNotification()
.ForDeviceToken(messageList[i].DeviceToken)//手機token
.WithAlert(messageList[i].Message)//推送消息內容
.WithBadge(7)//設備圖標顯示的未讀數(圖標右上角的小標志)
.WithSound("sound.caf"));//提示聲音
push.StopAllServices()//停止推送服務.
#region=====推送狀態事件
static void DeviceSubscriptionChanged(object sender, string oldSubscriptionId, string newSubscriptionId, INotification notification)
{
//Currently this event will only ever happen for Android GCM
//Console.WriteLine("Device Registration Changed: Old-> " + oldSubscriptionId + " New-> " + newSubscriptionId + " -> " + notification);
}
// 推送成功
static void NotificationSent(object sender, INotification notification)
{
}
// 推送失敗
static void NotificationFailed(object sender, INotification notification, Exception notificationFailureException)
{
//Console.WriteLine("Failure: " + sender + " -> " + notificationFailureException.Message + " -> " + notification);
}
static void ChannelException(object sender, IPushChannel channel, Exception exception)
{
//Console.WriteLine("Channel Exception: " + sender + " -> " + exception);
}
static void ServiceException(object sender, Exception exception)
{
//Console.WriteLine("Channel Exception: " + sender + " -> " + exception);
}
static void DeviceSubscriptionExpired(object sender, string expiredDeviceSubscriptionId, DateTime timestamp, INotification notification)
{
//Console.WriteLine("Device Subscription Expired: " + sender + " -> " + expiredDeviceSubscriptionId);
}
static void ChannelDestroyed(object sender)
{
//Console.WriteLine("Channel Destroyed for: " + sender);
}
static void ChannelCreated(object sender, IPushChannel pushChannel)
{
//Console.WriteLine("Channel Created for: " + sender);
}
#endregion
三.解決多信息推送,並且推送到不同的設備上.我寫了一個類,來做這些事.現在也給大家看看
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PushSharp.Apple;
using PushSharp.Core;
using PushSharp;
using System.IO;
using CYPInformationSystem.Model;
using System.Threading;
namespace CYPInformationSystem.PushMessage
{
/// <summary>
/// 描述:蘋果客戶端推送類
/// 作者:茹化肖
/// 時間:2014年7月4日16:19:40
/// </summary>
public class ApplePushService
{
private static ApplePushService applePushService;
private static readonly object syncObject = new object();
private PushBroker push;//創建一個推送對象
private List<MessageModel> messageList;//消息實體隊列
private readonly string appleCertpath = AppDomain.CurrentDomain.BaseDirectory +ConfigurationManager.AppSettings["appleCertpath"];
private readonly string appleCertPwd = ConfigurationManager.AppSettings["appleCertPwd"];//密碼
private ApplePushService()
{
//確保該對象被實例化
this.push = new PushBroker();
this.messageList = new List<MessageModel>();
//關聯推送狀態事件
push.OnNotificationSent += NotificationSent;
push.OnChannelException += ChannelException;
push.OnServiceException += ServiceException;
push.OnNotificationFailed += NotificationFailed;
push.OnDeviceSubscriptionExpired += DeviceSubscriptionExpired;
push.OnDeviceSubscriptionChanged += DeviceSubscriptionChanged;
push.OnChannelCreated += ChannelCreated;
push.OnChannelDestroyed += ChannelDestroyed;
}
#region=====公布給外接調用的方法
/// <summary>
/// 獲取對象實例
/// </summary>
/// <returns></returns>
public static ApplePushService GetInstance()
{
if (applePushService == null)
{
lock (syncObject)
{
if (applePushService == null)
{
applePushService = new ApplePushService();
applePushService.TherdStart();
}
}
}
return applePushService;
}
/// <summary>
/// 添加需要推送的消息
/// </summary>
/// <param name="message">消息體</param>
public void AddMessage(MessageModel message)
{
messageList.Add(message);
}
/// <summary>
/// 推送消息
/// </summary>
/// <param name="msg">消息體</param>
/// <param name="token">用戶token</param>
private void SendMessage()
{
try
{
var appleCert = File.ReadAllBytes(appleCertpath);
if (appleCert.Length > 0 && appleCert != null)//證書對象不為空
{
push.RegisterAppleService(new ApplePushChannelSettings(appleCert, appleCertPwd));
while (true)
{
if (messageList.Count > 0)//如果 消息隊列中的消息不為零 推送
{
for (int i = 0; i < messageList.Count; i++)
{
push.QueueNotification(new AppleNotification()
.ForDeviceToken(messageList[i].DeviceToken)
.WithAlert(messageList[i].Message).WithBadge(7)
.WithSound("sound.caf"));
}
messageList.Clear();//推送成功,清除隊列
}
else
{
//隊列中沒有需要推送的消息,線程休眠5秒
Thread.Sleep(5000);
}
}
}
}
catch (Exception e)
{
throw e;
}
}
/// <summary>
/// 啟動推送
/// </summary>
private void TherdStart()
{
Thread td = new Thread(SendMessage);
td.IsBackground = true;
td.Start();
}
#endregion
#region=====推送狀態事件
static void DeviceSubscriptionChanged(object sender, string oldSubscriptionId, string newSubscriptionId, INotification notification)
{
//Currently this event will only ever happen for Android GCM
//Console.WriteLine("Device Registration Changed: Old-> " + oldSubscriptionId + " New-> " + newSubscriptionId + " -> " + notification);
}
/// <summary>
/// 推送成功
/// </summary>
/// <param name="sender"></param>
/// <param name="notification"></param>
static void NotificationSent(object sender, INotification notification)
{
}
/// <summary>
/// 推送失敗
/// </summary>
/// <param name="sender"></param>
/// <param name="notification"></param>
/// <param name="notificationFailureException"></param>
static void NotificationFailed(object sender, INotification notification, Exception notificationFailureException)
{
//Console.WriteLine("Failure: " + sender + " -> " + notificationFailureException.Message + " -> " + notification);
}
static void ChannelException(object sender, IPushChannel channel, Exception exception)
{
//Console.WriteLine("Channel Exception: " + sender + " -> " + exception);
}
static void ServiceException(object sender, Exception exception)
{
//Console.WriteLine("Channel Exception: " + sender + " -> " + exception);
}
static void DeviceSubscriptionExpired(object sender, string expiredDeviceSubscriptionId, DateTime timestamp, INotification notification)
{
//Console.WriteLine("Device Subscription Expired: " + sender + " -> " + expiredDeviceSubscriptionId);
}
static void ChannelDestroyed(object sender)
{
//Console.WriteLine("Channel Destroyed for: " + sender);
}
static void ChannelCreated(object sender, IPushChannel pushChannel)
{
//Console.WriteLine("Channel Created for: " + sender);
}
#endregion
}
}
這里用單例來保證,整個應用程序中只會有這一個推送對象,只有一個管道來推送.
不然的話 你多次來注冊這個管道會報錯的.
還遇到過 一個問題,.Newtonsoft.Json 這個程序集有時候報錯,說版本不對. 這個程序集是類序列化消息的.
我的解決辦法是,去獲取PushSharp 的源碼.官方網站:https://github.com/Redth/PushSharp
然后自己編譯一下,將生成的Dll文件 拿過來 引用到你的項目中.就可以使用了 ,至於其他問題 和別的平台沒有去測試
