我在网上搜索过,找不到解决问题的方法。
我有一个针对.net Framework 4.0的项目。
我有两种方法。一个用于将通知推送到ios设备,另一个用于将通知推送到Android设备。
这是我的第一个方法:
public void SendAplePushNotificationMessage(string body, int Participant_ID, int Trainer_ID)
{
var componentSetup = new ComponentSetup();
var odsDevicesToken = componentSetup.getDevicesToken(Participant_ID, Trainer_ID, 1);
if (odsDevicesToken.Tables[0].Rows.Count > 0)
{
foreach (DataRow dr in odsDevicesToken.Tables[0].Rows)
{
try
{
var deviceToken = HexStringToByteArray(dr["DeviceToken"].ToString());
var memoryStream = new MemoryStream();
var writer = new BinaryWriter(memoryStream);
writer.Write((byte)0); //The command
writer.Write((byte)0); //The first byte of the deviceId length (big-endian first byte)
writer.Write((byte)32); //The deviceId length (big-endian second byte)
writer.Write(deviceToken);
writer.Write((byte)0); //First byte of payload length; (big-endian first byte)
var payload = "{\"aps\":{\"alert\":\"" + body + "\",\"badge\":1,\"sound\":\"default\"}}";
var b1 = Encoding.UTF8.GetBytes(payload);
if (b1.Length > 256)
{
body = body.Substring(0, 106) + "...";
payload = "{\"aps\":{\"alert\":\"" + body + "\",\"badge\":1,\"sound\":\"default\"}}";
b1 = Encoding.UTF8.GetBytes(payload);
}
writer.Write((byte)b1.Length);
writer.Write(b1);
writer.Flush();
var array = memoryStream.ToArray();
memoryStream.Write(Encoding.ASCII.GetBytes(body), 0, body.Length);
var port = Convert.ToInt32(ConfigurationManager.AppSettings["APNPortNo"]);
var hostname = ConfigurationManager.AppSettings["APNHostName"];
var certificatePath = Server.MapPath("~") + ConfigurationManager.AppSettings["APNCertificatePath"].Replace("/", "\\");
Logger.LogInfoMessage("certificatePath: " + certificatePath);
var clientCertificate = new X509Certificate2(File.ReadAllBytes(certificatePath), "");
var certificatesCollection = new X509Certificate2Collection(clientCertificate);
var client = new TcpClient(hostname, port);
var sslStream = new SslStream(client.GetStream(), false,
new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
try
{
sslStream.AuthenticateAsClient(hostname, certificatesCollection, SslProtocols.Tls, false);
sslStream.Write(array);
sslStream.Flush();
client.Close();
}
catch (AuthenticationException ex)
{
client.Close();
var setupObj = new ComponentSetup();
setupObj.AddErrorLog(ex.Message, CamelRaceContext.UserSettings.User.USER_NAME, null,
Participant_ID, dr["DeviceToken"].ToString());
if (ex.InnerException != null)
Logger.LogErrorMessage(ex.InnerException, ex.InnerException.Message);
throw new CamelRaceApplicationException<MobileAdmin_ManageNotifications>(ex.Message, ex);
}
catch (CamelRaceApplicationException<MobileAdmin_ManageNotifications> ex)
{
throw new CamelRaceApplicationException<MobileAdmin_ManageNotifications>(ex.Message,ex);
}
catch (Exception e)
{
client.Close();
var setupObj = new ComponentSetup();
setupObj.AddErrorLog(e.Message, CamelRaceContext.UserSettings.User.USER_NAME, null, Participant_ID, dr["DeviceToken"].ToString());
}
}
catch (CamelRaceApplicationException<MobileAdmin_ManageNotifications> ex)
{
throw new CamelRaceApplicationException<MobileAdmin_ManageNotifications>(ex.Message, ex);
}
catch (Exception exMain)
{
var setupObj = new ComponentSetup();
setupObj.AddErrorLog(exMain.Message, CamelRaceContext.UserSettings.User.USER_NAME, null, Participant_ID, dr["DeviceToken"].ToString());
if (exMain.InnerException != null)
Logger.LogErrorMessage(exMain.InnerException, exMain.InnerException.Message);
}
}
}
}
第二种方法是:
private void SendGCMPushNotificationMessage(string body, int Participant_ID, int Trainer_ID)
{
var _ComponentSetup = new ComponentSetup();
var odsDevicesToken = _ComponentSetup.getDevicesToken(Participant_ID, Trainer_ID , 2);
if (odsDevicesToken.Tables[0].Rows.Count > 0)
{
var registration_ids = new string[odsDevicesToken.Tables[0].Rows.Count];
var index = 0;
foreach (DataRow dr in odsDevicesToken.Tables[0].Rows)
{
registration_ids[index] = dr["DeviceToken"].ToString();
index = index + 1;
}
if (registration_ids.Length > 0)
{
var GcmHttpUrl = ConfigurationManager.AppSettings["GcmHttpUrl"];
var GcmApiKey = ConfigurationManager.AppSettings["GcmApiKey"];
var notificationData = new JObject(
new JProperty("registration_ids", new JArray(registration_ids)),
new JProperty("notification", new JObject(
new JProperty("title", ConfigurationManager.AppSettings["title"]),
new JProperty("body", body),
new JProperty("icon", "myicon"),
new JProperty("sound", "default")
)),
new JProperty("data", new JObject(
new JProperty("state", ConfigurationManager.AppSettings["state"])
)
)
);
var contentText = notificationData.ToString(Formatting.None);
var content = Encoding.UTF8.GetBytes(contentText);
try
{
var req = (HttpWebRequest)WebRequest.Create(GcmHttpUrl);
req.Method = "POST";
// Disable expect-100 to improve latency
req.ServicePoint.Expect100Continue = false;
req.ContentType = "application/json";
req.ContentLength = content.Length;
req.Headers.Add("Authorization", "key=" + GcmApiKey);
using (var s =req.GetRequestStream())
{
s.Write(content, 0, content.Length);
s.Close();
}
// Receive the HTTP response.
string response;
using (var res = (HttpWebResponse) req.GetResponse())
{
// Read the request body
using (TextReader r = new StreamReader(res.GetResponseStream(), Encoding.UTF8, true))
{
response = r.ReadToEnd();
}
}
Console.WriteLine("Response: " + response);
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.ToString());
var setupObj = new ComponentSetup();
setupObj.AddErrorLog("Exception: " + ex.ToString(), CamelRaceContext.UserSettings.User.USER_NAME, null, Participant_ID,null);
if (ex is WebException)
{
var webex = (WebException)ex;
if (webex.Response != null)
{
var status = ((HttpWebResponse)webex.Response).StatusCode;
setupObj.AddErrorLog("Exception: " + status.ToString(), CamelRaceContext.UserSettings.User.USER_NAME, null, Participant_ID, null);
// Check the status code here...
}
}
}
}
}
}
现在,当设备数量为3或4时,此代码正常工作。
当这个数字增加时。像8423一样。
它会导致应用程序挂起。
目前我在按钮点击时调用此代码。
我想知道将使用任务类放置此代码会使其工作吗?
var task1 = Task.Factory.StartNew(() =>SendAplePushNotificationMessage(txtNotification.Text, Participant_ID, Trainer_ID) , TaskCreationOptions.LongRunning);
var task2 = Task.Factory.StartNew(() => SendGCMPushNotificationMessage(txtNotification.Text, Participant_ID, Trainer_ID), TaskCreationOptions.LongRunning);
Task.WaitAll(task1, task2);
我知道有些人会建议使用pushsharp。
我在考虑这样做。
然而推动锐利目标4.5。
我的项目目标4.0。
升级不是一种选择。
我的解决方案能否运作?
如果没有,那我怎么解决我的问题呢。
感谢。