Pushsharp 4.0.10 "Connection Error" for IOS device tokens - ios

I developed windows service for sending push notifications to both iOS and Android apps using pushsharp library. Recently I updated the library from 2.x.x to 4.0.10 and GCM notifications are sending fine but Ios notifications are not sending, always getting "Connection Error" And I need to send notifications to thousands of tokens, So I am looping through all the tokens and queuing. Even for 10 tokens also getting same error.
Please suggest me what's wrong with my code. Here is my code snippet
public static void SendNotifications(List currentBrandNotications, long brandId)
{
byte[] appleCert = null;
string p12File = #"aps_production_brand" + brandId.ToString().Trim() + ".p12";
try
{
appleCert = File.ReadAllBytes(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "P12\\" + p12File));
}
catch (Exception ex)
{
logger.Debug("P12 certificate is not avilable for BrandId: " + brandId);
}
try
{
logger.Debug(" Send PushNotifications To Apple :- ");
if (appleCert != null)
{
// Configuration
var config = new ApnsConfiguration(ApnsConfiguration.ApnsServerEnvironment.Production, appleCert, currentBrandNotications[0].P12Password);
// Create a new broker
var apnsBroker = new ApnsServiceBroker(config);
var fbs = new FeedbackService(config);
// Wire up events
apnsBroker.OnNotificationFailed += (Notification, aggregateEx) =>
{
//ScheduledNotification ScheduledNotification = new InstantPNScheduler.ScheduledNotification();
aggregateEx.Handle(ex =>
{
// See what kind of exception it was to further diagnose
if (ex is ApnsNotificationException)
{
var notificationException = (ApnsNotificationException)ex;
// Deal with the failed notification
var apnsNotification = notificationException.Notification;
var statusCode = notificationException.ErrorStatusCode;
logger.Debug("Apple Notification Failed: ID=" + apnsNotification.Identifier + " Code=" + statusCode);
}
else
{
// Inner exception might hold more useful information like an ApnsConnectionException
logger.Debug(ex.InnerException.ToString());
}
// Mark it as handled
return true;
});
};
apnsBroker.OnNotificationSucceeded += (Notification) =>
{
logger.Debug("Apple Notification Sent!");
};
// Start the broker
apnsBroker.Start();
foreach (ScheduledNotification notification in currentBrandNotications)
{
try
{
//logger.Debug("iOS Device token=" + notification.DeviceToken); apnsBroker.QueueNotification(new ApnsNotification
{
DeviceToken = notification.DeviceToken,
Payload = JObject.Parse("{\"aps\":{\"alert\":\"" + notification.Message + "\",\"badge\":1,\"sound\":\"sound.caf\",\"BrandId\":\"" + brandId.ToString() + "\",\"notificationType\":\"Basic\",\"DeviceType\":\"" + notification.DeviceType + "\",\"DeviceToken\":\"" + notification.DeviceToken + "\",\"NotificationId\":\"" + notification.NotificationId + "\"}}")
});
}
Thread.Sleep(800);
}
catch (Exception ex)
{
logger.Debug(" SendPushNotificationToApple :- " + ex.Message);
}
}
// Stop the broker, wait for it to finish
// This isn't done after every message, but after you're
// done with the broker
apnsBroker.Stop();
}
}
catch (Exception ex)
{
logger.Debug("Error" + ex.Message);
}
finally
{
//apnsBroker = null;
}
}
Note : If I put thread.sleep(800) in for loop, then notifications will be sent but it's getting too late in case of thousands of tokens. I need it without thread.sleep(800), even If I reduce below 800ms, getting same exception.
Please help me what's wrong with my code.
Any help would be appreciated.

Related

Consuming a Web API in ASP.NET MVC using HttpClient. The response message is not what is sent back to the client from the web api

To consume a Web API in ASP.NET MVC server side I am using 'HttpClient'. HttpClient sends a request to the Web API and receives a response. Then I convert the response data that came from the Web API to a model and then render it into a view.
The problem is when there is an error in the web api, my client is not receiving the custom error message that was sent.
The web api sends a status code = 400 and a ReasonPhrase with my custom message, but when it gets to the client, it is a status code = 500 and the ReasonPhrase = 'Internal Server error'.
Why?
Web api code - the WebApi2Controller method called by the client which calls a data access layer then sends result back to client:
[HttpPost]
[Route("getbloggersinfo/{argsData}/")]
public IHttpActionResult GetBloggersInfo(ArgsToPassToApi argsToPassToApi)
{
IHttpActionResult httpActionResult;
HttpResponseMessage httpResponseMessage;
try
{
BloggerInfoResults bloggerInfoResults = new BloggerInfoResults();
bloggerInfoResults = dataAccessLayer.GetBloggersInfo(argsToPassToApi.UserName, argsToPassToApi.IpAddress);
httpResponseMessage = Request.CreateResponse(HttpStatusCode.OK, bloggerInfoResults);
}
catch (Exception ex)
{
httpResponseMessage = Request.CreateResponse(HttpStatusCode.BadRequest);
httpResponseMessage.ReasonPhrase = ex.Message;
}
httpActionResult = ResponseMessage(httpResponseMessage);
return httpActionResult;
}
The web api code - the data access layer method called by the WebApi2Controller:
public BloggerInfoResults GetBloggersInfo(string userName, string ipAddress)
{
string userFriendlyMessage = "Unable to get the Blogger's info. We have been notified and are working to resolve this. Please do not continue.";
BloggerInfoResults bloggerInfoResults = new BloggerInfoResults();
SqlDataReader bloggerInfoDataReader = null;
try
{
dbFunc.OpenDB();
SqlCommand cmd = new SqlCommand("dbo.GetBloggersInfo", dbFunc.objConn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("#a_UserName", userName);
cmd.Parameters.AddWithValue("#a_IpAddress", ipAddress);
bloggerInfoDataReader = cmd.ExecuteReader();
while (bloggerInfoDataReader.Read())
{
bloggerInfoResults.UserId = Convert.ToInt32(bloggerInfoDataReader["UserId"]);
bloggerInfoResults.UserName = bloggerInfoDataReader["UserName"].ToString();
bloggerInfoResults.HasProfileSwitch = Convert.ToBoolean(bloggerInfoDataReader["HasProfileSwitch"]);
}
return bloggerInfoResults;
}
catch (SqlException sqlex)
{
if (sqlex.Message.Contains("Critical"))
{
// A "critical" error coming from the stored procedure.
currentDateTime = DateTime.Now;
sendAlertEmailResult = SendAlertEmailToStaff(currentDateTime, userName, ipAddress);
if (sendAlertEmailResult == "")
{
// The alert email was sent successfully.
// Throw - for setting the UI. Send a user friendly message.
throw new Exception(userFriendlyMessage);
}
else
{
// Not sent successfully. I have no choice but to send the verbose message as it was NOT stored in the error log and I will need to see it
// when debugging.
// Throw - for setting the UI.
throw new Exception(criticalErrorPrepend + "Error in DataAccessLayer/GetBloggersInfo(). Sending an alert email for the initial sql exception error: " + sqlex.Message + ". Now getting this error: " + sendAlertEmailResult);
}
}
else
{
// Not coming from the stored procedure. Like if the stored procedure above was not named properly, does not exist, parameter missing, etc.
errorMessage = "Sql Exception Error in DataAccessLayer/GetBloggersInfo(). Using 'GetBloggersInfo' s/p. Error: " + sqlex.Message;
// Log the error and send an alert email.
currentDateTime = DateTime.Now;
processErrorLogAndSendAlertEmailResult = ProcessErrorLogAndSendAlertEmail(currentDateTime, userName, errorMessage, additionalInfoForLog, ipAddress);
if (processErrorLogAndSendAlertEmailResult != "")
{
// Throw - for setting the UI.
throw new Exception(criticalErrorPrepend + "Error in DataAccessLayer/GetBloggersInfo(). Using 'GetBloggersInfo' s/p. Logging the initial sql exception error: " + sqlex.Message + ". Now getting this error: " + processErrorLogAndSendAlertEmailResult);
}
else
{
// Throw - for setting the UI. Send a user friendly message.
throw new Exception(userFriendlyMessage);
}
}
}
catch (Exception ex)
{
errorMessage = "Error in DataAccessLayer/GetBloggersInfo(). Using 'GetBloggersInfo' s/p. Error: " + ex.Message;
// Log the error and send an alert email.
currentDateTime = DateTime.Now;
processErrorLogAndSendAlertEmailResult = ProcessErrorLogAndSendAlertEmail(currentDateTime, userName, errorMessage, additionalInfoForLog, ipAddress);
if (processErrorLogAndSendAlertEmailResult != "")
{
// Throw - for setting the UI.
throw new Exception(criticalErrorPrepend + "Error in DataAccessLayer/GetBloggersInfo(). Using 'GetBloggersInfo' s/p. Logging the initial error: " + ex.Message + ". Now getting this error: " + processErrorLogAndSendAlertEmailResult);
}
else
{
// Throw - for setting the UI. Send a user friendly message.
throw new Exception(userFriendlyMessage);
}
}
finally
{
if (bloggerInfoDataReader != null)
{
// Close the reader.
bloggerInfoDataReader.Close();
}
// Close the database.
dbFunc.CloseDB();
}
}
The custom message being thrown (throw new Exception (....)) from the data access layer method back to the WebApi2Controller method (my custom message):
The error being sent to the client from the WebApi2Controller (a status code = 400 and ReasonPhrase with my custom message):
The client code which calls the web api controller method using httpclient:
public async Task<BloggerInfoResults> GetBloggersInfo(string userName, string webApiUrl, string myIpAddress)
{
try
{
BloggerInfoResults bloggerInfoResults = new BloggerInfoResults();
ArgsToPassToApi argsToPassToApi = new ArgsToPassToApi();
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(webApiUrl);
argsToPassToApi.UserName = userName;
argsToPassToApi.IpAddress = myIpAddress;
string restOfUrl = "/api/profileandblog/getbloggersinfo/" + argsToPassToApi + "/";
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
string payLoad = JsonConvert.SerializeObject(argsToPassToApi);
HttpContent argsData = new StringContent(payLoad, Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync(restOfUrl, argsData);
if (response.IsSuccessStatusCode)
{
var entry = response.Content.ReadAsStringAsync().Result;
bloggerInfoResults = JsonConvert.DeserializeObject<BloggerInfoResults>(entry);
}
else
{
// The web api sent an error response.
bloggerInfoResults.ApiErrorMessage = "Web api error. Reason: " + response.ReasonPhrase;
}
// Return the model.
return bloggerInfoResults;
}
}
catch (Exception)
{
throw;
}
}
The error being received (a status code = 400 and the ReasonPhrase = 'Internal Server error'.):

How to update pin information on google map using xamarin

It is necessary to replace the direct connection to the database with API.
I use this code to directly connect to MySQL db and change pin information:
public async void DatabaseConnection(List<CustomPin> pins)
{
string ConnectionString = "server=192.168.0.1;uid=user;port=4444;pwd=pass;database=dbName;";
MySqlConnection Conn = new MySqlConnection(ConnectionString);
try
{
Conn.Open();
string query = "SELECT * FROM sel_alert_level s;";
MySqlCommand myCommand = new MySqlCommand(query, Conn);
MySqlDataReader myReader;
myReader = myCommand.ExecuteReader();
try
{
while (myReader.Read())
{
int codeNum = myReader.GetInt32(4);
int level = myReader.GetInt32(3);
int mapCode = myReader.GetInt32(0);
foreach (var item in pins)
{
if (item.CodeNum == codeNum)
{
item.AlertLevel = level;
item.CodeNum = codeNum;
item.MapCode = mapCode;
//await DisplayAlert("Alert", mapCode.ToString(), "ok");
}
}
//await DisplayAlert("Database Connection", "Connected .." + Environment.NewLine + myReader.GetInt32(0) + Environment.NewLine + myReader.GetString(1) + Environment.NewLine + myReader.GetString(2) + Environment.NewLine + myReader.GetInt32(3) + Environment.NewLine + myReader.GetInt32(4), "OK");
}
}
finally
{
myReader.Close();
Conn.Close();
}
}
catch (Exception ex)
{
await DisplayAlert("Database Connection", "Not Connected ..." + Environment.NewLine + ex.ToString(), "OK");
}
}
With this code I successfully update the pin information.
Now I create the same method with API Response and what to do the same like DatabaseConnection(); just try to update the information, but not work for me :(
public async void APIConnection(List<CustomPin> pins)
{
try
{
WaterBindingData waterData = await _restServiceData.GetWaterDataForecast(GenerateRequestUriStations(Constants.EndPoint), GenerateRequestUri(Constants.EndPoint));
foreach (var water in waterData.WaterStation.Stations)
{
foreach (var item in pins)
{
if (item.CodeNum == water.CodeNum)
{
item.AlertLevel = water.AlertLevelStation;
item.CodeNum = water.CodeNum;
item.MapCode = water.MapCode;
}
}
}
}
catch (Exception ex)
{
await DisplayAlert("Data Alert", "Error:" + Environment.NewLine + ex.ToString(), "OK");
}
}
I not have any errors here. waterData come with the data, but data not changed in the pins.. I don't know why...
And Now my information are not changed ..
MapCode and other variables not changed.
I call this two methods in the constructor like that:
DatabaseConnection(customMap.CustomPins);
APIConnection(customMap.CustomPins);
So... When I start the project I receive message like this:
/Applications/Visual Studio.app/Contents/Resources/lib/monodevelop/bin/MSBuild/Current/bin/Microsoft.Common.CurrentVersion.targets(5,5): Warning MSB3276: Found conflicts between different versions of the same dependent assembly. Please set the "AutoGenerateBindingRedirects" property to true in the project file. For more information, see http://go.microsoft.com/fwlink/?LinkId=294190. (MSB3276) (MaritsaTundzhaForecast.iOS)
And I check this link but I not have properties option, because I use mac. I have only options on the projects.
Is it possible that this does not change the content in the pins аnd what would be the reason it didn't work ?
I checked the if statement in the loop and she work:
Since it is an asynchronous method , I suggest you try to assign customMap.CustomPins in APIConnection method .
Something like that
//constructor
List<CustomPin> pins = xxxxx;
APIConnection(pins);
public async void APIConnection(List<CustomPin> pins)
{
try
{
WaterBindingData waterData = await _restServiceData.GetWaterDataForecast(GenerateRequestUriStations(Constants.EndPoint), GenerateRequestUri(Constants.EndPoint));
foreach (var water in waterData.WaterStation.Stations)
{
foreach (var item in pins)
{
if (item.CodeNum == water.CodeNum)
{
item.AlertLevel = water.AlertLevelStation;
item.CodeNum = water.CodeNum;
item.MapCode = water.MapCode;
}
}
}
customMap.CustomPins = pins; //assign the value in this line
}
catch (Exception ex)
{
await DisplayAlert("Data Alert", "Error:" + Environment.NewLine + ex.ToString(), "OK");
}
}

PushSharp Apns notification error: 'ConnectionError'

I'm using PushSharp 4.0.10, MVC 4 with c#
In the OnNotificationFailed event of the Apns broker, I get ConnectionError exception.
This exception happened suddenly after change certificate(.p12) file; and it worked fine before this change.
Please advise how to troubleshoot this error.
var certificate = System.IO.File.ReadAllBytes(System.Web.Hosting.HostingEnvironment.MapPath("~/Content/Mobile/consumer_dev.p12"));
var config = new ApnsConfiguration(ApnsConfiguration.ApnsServerEnvironment.Sandbox, certificate, "", true);
var apnsBroker = new ApnsServiceBroker(config);
apnsBroker.OnNotificationFailed += (notification, aggregateEx) => {
aggregateEx.Handle (ex => {
if (ex is ApnsNotificationException) {
var notificationException = (ApnsNotificationException)ex;
var apnsNotification = notificationException.Notification;
var statusCode = notificationException.ErrorStatusCode;
Debug.WriteLine(apnsNotification.Identifier + ", " + statusCode);
} else {
Debug.WriteLine(ex.InnerException);
}
return true;
});
};
apnsBroker.OnNotificationSucceeded += (notification) => {
Debug.WriteLine("Apple Notification Sent!");
};
apnsBroker.Start();
foreach (var deviceToken in to)
{
apnsBroker.QueueNotification(new ApnsNotification
{
DeviceToken = deviceToken,
Payload = JObject.Parse("{\"aps\":" + aps.ToString().Replace('=', ':') + "}")
});
}
apnsBroker.Stop();
this error is because certificate you used is not enabled pushnotification.
you have to to enable it from apple id and then create new certificate (.12) and provisioning profile.
try with that new certificate will resolve your error.
Try by passing only first two parameters to apnsconfiguration constructor, or else remove validateIsApnsCertificate (bool ) parameter.
It's working fine for me first three parameters.
var config = new ApnsConfiguration(ApnsConfiguration.ApnsServerEnvironment.Production, appleCert, P12Password);

Incoming sms listener on blackberry

i've used below code for notify the sms .
Its working on two blackberry simulator.
I've install the app on my device and send sms from android device.
The sms listener not working on device.
Incoming message received on device. but my app not notify the listener .
What is the problem how to resolve it.
What port number need to give for device?
class BackgroundApplication extends Application implements MessageListener
{
int i=0;
static String suffix;
MessageConnection _mc ;
public BackgroundApplication()
{
try {
_mc = (MessageConnection)Connector.open("sms://:0");
_mc.setMessageListener(this);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void notifyIncomingMessage(MessageConnection conn) {
try {
Message m = _mc.receive();
String address = m.getAddress();
String msg = null;
if ( m instanceof TextMessage )
{
TextMessage tm = (TextMessage)m;
msg = tm.getPayloadText();
}
else if (m instanceof BinaryMessage) {
StringBuffer buf = new StringBuffer();
byte[] data = ((BinaryMessage) m).getPayloadData();
// convert Binary Data to Text
msg = new String(data, "UTF-8");
}
else
System.out.println("Invalid Message Format");
System.out.println("Received SMS text from " + address + " : " + msg);
showDialog("Msg: "+msg);
} catch (Exception e) {
// TODO: handle exception
}
}
private void showDialog(String string) {
synchronized (UiApplication.getEventLock())
{
Status.show(""+string,Bitmap.getPredefinedBitmap(Bitmap.INFORMATION), 5000,
Status.GLOBAL_STATUS, true, false, 1);
}
}
}
Check this
http://supportforums.blackberry.com/t5/Java-Development/Different-ways-to-listen-for-SMS-messages/ta-p/445062
DatagramConnection _dc =
(DatagramConnection)Connector.open("sms://");
for(;;)
{
Datagram d = _dc.newDatagram(_dc.getMaximumLength());
_dc.receive(d);
byte[] bytes = d.getData();
String address = d.getAddress();
String msg = new String(bytes);
System.out.println( "Received SMS text from " + address + " : " + msg);
}

Parse IMAP message and extract header information

I am trying to extract header and body information from email, the following code retrieves the header and body in their raw form. I have an email object that contains the fields from, subject, date, and body. I would like to extract these values from the email and assign them to the email object. How do I get around it? I have tried several ways like getting the header info and using a streamReader.ReadLine() to get a line but I got illegal path exceptions. I know I can use a library but I need to achieve it this way.
What I mean is this, IMAP command returns header information. And I want to extract subject value, date value, sender e-amil, etc. and assign them to my email objects corresponding values like
emailObject.subject = "subjectValue"
public class Imap
{
static void Main(string[] args)
{
try
{
path = Environment.CurrentDirectory + "\\emailresponse.txt";
if (System.IO.File.Exists(path))
System.IO.File.Delete(path);
sw = new System.IO.StreamWriter(System.IO.File.Create(path));
tcpc = new System.Net.Sockets.TcpClient("imap.gmail.com", 993);
ssl = new System.Net.Security.SslStream(tcpc.GetStream());
ssl.AuthenticateAsClient("imap.gmail.com");
receiveResponse("");
Console.WriteLine("username : ");
username = Console.ReadLine();
Console.WriteLine("password : ");
password = Console.ReadLine();
receiveResponse("$ LOGIN " + username + " " + password + " \r\n");
Console.Clear();
receiveResponse("$ LIST " + "\"\"" + " \"*\"" + "\r\n");
receiveResponse("$ SELECT INBOX\r\n");
receiveResponse("$ STATUS INBOX (MESSAGES)\r\n");
Console.WriteLine("enter the email number to fetch :");
int number = int.Parse(Console.ReadLine());
Console.WriteLine("*************Header************");
Console.WriteLine("");
// receiveResponse("$ FETCH " + number + " body[header]\r\n");
// BODY.PEEK[HEADER.FIELDS (SUBJECT)]
// StringBuilder sb = receiveResponse("$ FETCH " + number + " BODY.PEEK[HEADER.FIELDS (From Subject Date)]\r\n");
StringBuilder sb= receiveResponse("$ FETCH " + number + " body.peek[header]\r\n");
Console.WriteLine(sb);
Console.WriteLine("");
Console.WriteLine("Body");
sb = new StringBuilder();
sb=receiveResponse("$ FETCH " + number + " body[text]\r\n");
System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
byte[] serverbuff = new Byte[1024];
int count = 0;
string retval = enc.GetString(serverbuff, 0, count);
Console.WriteLine(sb.ToString());
receiveResponse("$ LOGOUT\r\n");
}
catch (Exception ex)
{
Console.WriteLine("error: " + ex.Message);
}
finally
{
if (sw != null)
{
sw.Close();
sw.Dispose();
}
if (ssl != null)
{
ssl.Close();
ssl.Dispose();
}
if (tcpc != null)
{
tcpc.Close();
}
}
Console.ReadKey();
}
static StringBuilder receiveResponse(string command)
{
sb = new StringBuilder();
try
{
if (command != "")
{
if (tcpc.Connected)
{
dummy = Encoding.ASCII.GetBytes(command);
ssl.Write(dummy, 0, dummy.Length);
}
else
{
throw new ApplicationException("TCP CONNECTION DISCONNECTED");
}
}
ssl.Flush();
buffer = new byte[2048];
bytes = ssl.Read(buffer, 0, 2048);
sb.Append(Encoding.ASCII.GetString(buffer));
// Console.WriteLine(sb.ToString());
sw.WriteLine(sb.ToString());
// sb = new StringBuilder();
return sb;
}
catch (Exception ex)
{
throw new ApplicationException(ex.Message);
}
}
You said you do not want to use an IMAP library. This means that you will have to implement your own. You should start by reading RFC 3501 because there is no chance you could get the protocol right without reading the docs carefuly. In particular, you're issuing a STATUS command on the currently selected mailbox, which is explicitly forbidden by the protocol specification. The rest of the code supports the assumption that you have not read the RFC yet.

Resources