03-03-2010 04:49 PM
Hello all,
I am making the transition from MDS to Widgets and in the process I have learned how to push data to an application listening on the correct port. My next step in Push is to emulate the MDS Runtime push and be able to 'push and forget'.
I would like to be able to push data to a device, and have that message stay queued up until the user is in service and his/her port is listening for the information. How can I make this happen?
Thanks,
J. Mace
03-08-2010 03:49 PM
You can make use of reliable push and push notifications to accomplish this.
There is no way to queue a message indefinitely on a BlackBerry Enterprise Server. However, by using push notification and push reliability your application can be informed whether or not the push was delivered to the user. If the push was not delivered your application can submit it again. I recommend making use of a throttling system that waits an increasing amount of time between retires.
The httppushdemo included with the BlackBerry JDE and BlackBerry Java Plug-in for Eclipse show examples on the use of this. You can also read about push notification here:
What Is - The Push notification format
03-10-2010 02:48 PM
Thanks for the reply Mark.
My issue is due to the fact that widgets can not run on the startup of the phone. This means that my pushlistener isn't active until a user opens the application once.
I am using the x-rim-push-reliability-mode 'application' and setting a push ID as well as a notification url, but I always get a return that the push was successful.
This causes my data to become out of sync from the desktop to the client phone. I have administrators thinking that a user has or does not have a piece of data and the opposite being true.
what I think it all boils down to...
Is there a way to queue a push until the pushlistener of a device is available to catch that pushed data?
03-11-2010 12:20 PM
What you could do is send a "I running" message when the Widget is launched and a "I'm closed" on application exit so that your back end server knows if the application is actually on.
03-26-2010 08:31 AM
The "running" and "closed" messaging system might work for most, but I am in a region where coverage is very spotty. My users go on and off of the grid multiple times a day for long periods of time.
I know RIM has successfully set up a similar system with the EOL'ed MDS Runtime applications. There has to be some way to emulate the same strengths of that server side system while taking advantage of the new client opportunities that widgets bring to the table.
05-10-2010 10:42 AM
I'm still trying to find a good solution for this.
I've added the "X-Rim-Push-Reliability" header of "application-preferred" . From what I've read out of the links provdied by MSohm (thanks), this should send a notification when the pushed message hits the port of my device it is sent to. I tested this by pushing a message with the app (and port) open a couple of times as well as pushing with the app and port closed. The messages with the app/port open were successful. The messages with the app/port closed failed, and didn't queue until I reopened the application after 2 minutes.
However, every push did respond back to my notification url... Seems like I'm still missing a small piece.
05-10-2010 03:18 PM
You should receive a notification (success or fail) to your notification URL for every push you submit.
05-10-2010 03:54 PM
I agree Mark. My problem is knowing which pushed message never makes it to my device.
I am doing both the push and capturing of the notification in a web service (.NET). My push notification "catcher" is called with the push ID. How can I derive at that point whether or not the push message has successfully been captured by my application?
[WebMethod]
public bool pushToWidget(string pushedMessage, string pushPin)
{
bool success = true;
byte[] bytes = Encoding.ASCII.GetBytes(pushedMessage);
Stream requestStream = null;
HttpWebResponse HttpWRes = null;
HttpWebRequest HttpWReq = null;
try
{
//http://<BESName>:<BESPort>/push?DESTINATTION=<PI N/EMAIL>&PORT=<PushPort>&REQUESTURI=/
// Build the URL to define our connection to the BES.
string httpURL = "http://" + BESAddress + ":" + BESWebserverListenPort
+ "/push?DESTINATION=" + pushPin + "&PORT=" + pushPort
+ "&REQUESTURI=/";
//make the connection
HttpWReq = (HttpWebRequest)WebRequest.Create(httpURL);
HttpWReq.Method = ("POST");
//add the headers nessecary for the push
HttpWReq.ContentType = "text/plain";
HttpWReq.ContentLength = bytes.Length;
// ******* Test this *******
HttpWReq.Headers.Add("X-Rim-Push-Id", pushPin + "~" + DateTime.Now); //"~" +pushedMessage +
HttpWReq.Headers.Add("X-Rim-Push-Reliability", "application-preferred");
HttpWReq.Headers.Add("X-Rim-Push-NotifyURL", (widgetNotificationUrl + pushPin + "~" + pushedMessage + "~" + DateTime.Now).Replace(" ",""));
// *************************
HttpWReq.Credentials = new MdsCredentials(pushUserName, pushPassword);
Console.WriteLine(pushedMessage);
requestStream = HttpWReq.GetRequestStream();
//Write the data from the source
requestStream.Write(bytes, 0, bytes.Length);
//get the response
HttpWRes = (HttpWebResponse)HttpWReq.GetResponse();
//if the MDS received the push parameters correctly it will either respond with okay or accepted
if (HttpWRes.StatusCode == HttpStatusCode.OK || HttpWRes.StatusCode == HttpStatusCode.Accepted)
{
success = true;
}
else
{
success = false;
}
//Close the streams
HttpWRes.Close();
requestStream.Close();
}
catch (System.Exception e)
{
success = false;
}
return success;
}
05-11-2010 11:06 AM - edited 05-11-2010 11:07 AM
The push notification will have a status code of 200 for a successful push and a status code of 400 for an unsuccessful push.
The Push notification format
05-11-2010 03:29 PM - edited 05-11-2010 04:08 PM
Thanks Mark, I'm aware of the status codes. My problem is I am always getting a success (200) even though my application does not always get the push.
*Edit
I should elaborate, if my application is open/closed and I do a push, I always get a 200 response. This is,despite my application being closed and not recieving the push (...the push listener is not subscribed when a widget is not running...). In this instance, i would expect a 400 to be returned since the reliability is set to the application level.
Now... if I turn off the radio on my device and wait 10 minutes, I do get a 400 response. I expect this behavior and agree with it.
[WebMethod]
public void pushNotificationCatch(string pushID)
{
IServiceProvider provider = (IServiceProvider)HttpContext.Current;
// Get the request
HttpRequest util = (HttpRequest)provider.GetService(typeof(HttpReques t));
string pushStatus = util.Headers.Get("X-RIM-Push-Status");
StringBuilder query = new StringBuilder();
query.Append("INSERT INTO TalonLog (Date,Application,Message,isError) VALUES ('" + DateTime.Now.ToString() + "','Talon web service','Test: " + pushStatus +"', 0 )");
DataAccess.ExecuteSQLQuery(query);
//X-RIM-Push-Status
string myPin = pushID.Split('~')[0];
string myMessage = pushID.Split('~')[1];
string myDate = pushID.Split('~')[2];
}