I'm developing a Windows Phone 8 app that uses Raw Notification. For this, I'm following the sample "How to send and receive raw notifications for Windows Phone 8".
I coded exactly as the sample:
public MainPage()
{
/// Holds the push channel that is created or found.
HttpNotificationChannel pushChannel;
// The name of our push channel.
string channelName = "RawSampleChannel";
InitializeComponent();
// Try to find the push channel.
pushChannel = HttpNotificationChannel.Find(channelName);
// If the channel was not found, then create a new connection to the push service.
if (pushChannel == null)
{
pushChannel = new HttpNotificationChannel(channelName);
// Register for all the events before attempting to open the channel.
pushChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(PushChannel_ChannelUriUpdated);
pushChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(PushChannel_ErrorOccurred);
pushChannel.HttpNotificationReceived += new EventHandler<HttpNotificationEventArgs>(PushChannel_HttpNotificationReceived);
pushChannel.Open();
}
else
{
// The channel was already open, so just register for all the events.
pushChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(PushChannel_ChannelUriUpdated);
pushChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(PushChannel_ErrorOccurred);
pushChannel.HttpNotificationReceived += new EventHandler<HttpNotificationEventArgs>(PushChannel_HttpNotificationReceived);
// Display the URI for testing purposes. Normally, the URI would be passed back to your web service at this point.
System.Diagnostics.Debug.WriteLine(pushChannel.ChannelUri.ToString());
MessageBox.Show(String.Format("Channel Uri is {0}",
pushChannel.ChannelUri.ToString()));
}
}
After I ran the code in a device, I saw that the app is generating a different URI each time I launch it.
I realized that HttpNotificationChannel.Find(channelName) is always returning null (that's why the app is always generating a new URI).
I already read this, but still didn't help me.
So, my question is:
Shouldn't HttpNotificationChannel.Find(channelName) returns something different from 'null' if the app had already generated a channel?
If I missed something that could help, please tell me.
I went through your post and the mentioned links. It seems channelUri updation is pretty random (usually it would certainly change for app uninstall/install, but there maybe other scenarios as well). One sure-shot way of ensuring your users are targeted properly is to associate the channelUri with another unique identifier. For instance, after grabbing the channelUri you might want to update the server database with the uri and a unique user id. For subsequest calls, only the channel may be updated for the same user. Hope this helps a bit.
Related
I have a Line-of-Business (LoB) Windows 8.1 Store application I developed for a client. The client side-loads it on several Windows 10 tablets. They use it in an environment where WiFi is spotty at best and they would like to get some sort of notification inside the app, regardless of what page they are on, notification that will let them know that they've lost connectivity to the network. I have created a method on my Web API that is not hitting the repository (database). Instead, it quickly returns some static information regarding my Web API, such as version, date and time of the invocation and some trademark stuff that I'm required to return. I thought of calling this method at precise intervals of time and when there's no response, assume that the Web API connectivity is lost. In my main page, the first one displayed when the application is started, I have the following stuff in the constructor of my view model:
_webApiStatusTimer = new DispatcherTimer();
_webApiStatusTimer.Tick += OnCheckWebApiStatusEvent;
_webApiStatusTimer.Interval = new TimeSpan(0, 0, 30);
_webApiStatusTimer.Start();
Then, the event handler is implemented like this:
private async void OnCheckWebApiStatusEvent(object sender, object e)
{
// stop the timer
_webApiStatusTimer.Stop();
// refresh the search
var webApiInfo = await _webApiClient.GetWebApiInfo();
// add all returned records in the list
if (webApiInfo == null)
{
var messageDialog = new MessageDialog(#"The application has lost connection with the back-end Web API!");
await messageDialog.ShowAsync();
// restart the timer
_webApiStatusTimer.Start();
}
}
When the Web API connection is lost, I get a nice popup message that informs me that the Web API is no longer available. The problem I have is that after a while, especially if I navigate away from the first page but not necessary, I get an UnauthorizedAccessException in my application.
I use the DispatcherTimer since my understanding is that this is compatible with
UI threads, but obviously, I still do something wrong. Anyone cares to set me on the right path?
Also, if you did something similar and found a much better approach, I'd love to hear about your solution.
Thanks in advance,
Eddie
First, If you are using Windows Store Apps, then you could possibly use a Background task to check poll for the status of the web api instead of putting this responsibility on your view model, its not the viewmodels concern
Second, if you are connecting from your Windows store app to your API then one successful authentication/ authorization for the first time, how and where do you store the token (assuming you are using token authentication). If you are (and ideally you should), is there a timer that you start which is set to the token expiration time? Is your local storage getting flushed somehow and loosing the aurthorization data?
Need more information.
I'm developing a server-side application to upload files to Box. I'm using the Box .NET SDK, using JWT for authentication.
Here's how I set up my Box stuff:
var boxConfig = new BoxConfig(clientId, clientSecret, enterpriseId, jwtPrivateKey, jwtPrivateKeyPassword, jwtPublicKeyId);
var boxJwt = new BoxJWTAuth(boxConfig);
var userToken = boxJwt.UserToken(boxAppUserId);
var userClient = boxJwt.UserClient(userToken, boxAppUserId);
Then I use the UserClient object to upload a file to Box once a day.
My question is: Will that UserClient or UserToken ever expire? I want to know if I should get a new UserToken and instantiate a UserClient every time I need to use it, or if I could initialize all these things just once when my application starts up.
The token will expire after roughly one hour. The client is designed to fetch a new user/admin token as necessary so you shouldn't need to worry about it after the client is initially created. You might even try specifying a blank token when initializing the client and let the re-authentication logic handle things from the beginning:
var userClient = boxJwt.UserClient("", boxAppUserId);
Following is the code for WP8 push notification.
HttpNotificationChannel pushChannel = new HttpNotificationChannel(channelName);
// Register for all the events before attempting to open the channel.
pushChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(PushChannel_ChannelUriUpdated);
pushChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(PushChannel_ErrorOccurred);
// Register for this notification only if you need to receive the notifications while your application is running.
pushChannel.ShellToastNotificationReceived += new EventHandler<NotificationEventArgs>(PushChannel_ShellToastNotificationReceived);
pushChannel.Open();
// Bind this new channel for toast events.
pushChannel.BindToShellToast();
pushChannel.BindToShellTile();
As you can see in above code I am binding pushChannel to shellToast as well as shellTile. I want to know is it valid or not? since I haven't got any doc on msdn regarding this. If it is possible and server sends any of the notifications will it be shown properly?
Please give your valuable feedback on this.
It is possible and it is the right way to do it. One app, one channel, no matter how many kinds of push notifications you use.
I have developed wp8 app,
I am updating my app tile at some scenarios,
here the code i have used for update my tile
ShellTile TileToFind = ShellTile.ActiveTiles.First();
StandardTileData NewTileData = new StandardTileData
{
BackgroundImage = new Uri(#"/ApplicationTile.png", UriKind.RelativeOrAbsolute),
Count = NotificationCount,
BackTitle = offers.data.info[0].offer_title,
BackContent = offers.data.info[0].location_area,
};
TileToFind.Update(NewTileData);
Here my doubt is, is it possible to set navigation uri for the BackTile, like as i give the navigation uri in my toast message here
Microsoft.Phone.Shell.ShellToast toast = new Microsoft.Phone.Shell.ShellToast();
toast.Content = "#" + offers.data.info[0].location_area;
toast.Title = offers.data.info[0].offer_title;
toast.NavigationUri = new Uri("/LocationDealsPage.xaml", UriKind.Relative);
toast.Show();
I need to navigate to different pages while click the back tile and front tile.
Anybody please let me know, is that possible are not, if possible please let me know how.
If not possible is there any other way to do this.
Thank you.
Noorul.
There is no way to set a different URI to navigate to when the user taps a tile when the back is displayed.
If you need to navigate to different parts of the app you could use multiple tiles.
Alternatively, if you're remotely updating the back of the tile when there is new information available and you want to do a different action when launching the app and there is new information (e.g. go to straight to that new item rather than the main page) you could do this check when the app is opened. To avoid having to make a[n extra] network request on app start up, you could use a background agent to regularly pull down the latest data (including a flag to detect if there is a new item) so it's there when the app is launched.
was trying to encapsulate a partial view to show feedback that i can push back to the client.
This Article shows a method of pushing back data using HTML5 Server-Sent events (SSE).
I noticed that if i opened up several browser tabs and then closed one i got exceptions as the logic didn't remove the respective stream from the ConcurrentQueue. I amended the code as below
private static void TimerCallback(object state)
{
StreamWriter data;
Random randNum = new Random();
// foreach (var data in _streammessage)
for (int x = 0; x < _streammessage.Count; x++)
{
_streammessage.TryDequeue(out data);
data.WriteLine("data:" + randNum.Next(30, 100) + "\n");
try
{
data.Flush();
_streammessage.Enqueue(data);
}
catch (Exception ex)
{
// dont re-add the stream as an error ocurred presumable the client has lost connection
}
}
//To set timer with random interval
_timer.Value.Change(TimeSpan.FromMilliseconds(randNum.Next(1, 3) * 500), TimeSpan.FromMilliseconds(-1));
}
I also had to amend the OnStreamAvailable member as the framework syntax had changed to the second parameter being a HttpContent rather than HttpContentHeaders
public static void OnStreamAvailable(Stream stream, HttpContent headers, TransportContext context)
The problem now is i am still getting inconsistant behaviour if i add or remove clients i.e it times out when trying to initialise a new client. Does anyone have any ideas or more examples of using SSE with WinAPI and the correct "framework of methods" to handle disconnected clients
Cheers
Tim
This article is actually an adaptation of my original article from May - http://www.strathweb.com/2012/05/native-html5-push-notifications-with-asp-net-web-api-and-knockout-js/ (notice even variable names and port numbers are the same :-).
It is a very valid point that you are raising, and detecting a broken connection is something that's not very easy with this setup. The main reason is that while ASP.NET (the host) allows you to check a broken connection, there is no notification mechanism between ASP.NET (host) and Web API informing about that.
That is why in order to detect a broken connection (disconnected client) you should really try writing to the stream, and catch any error - this would mean the client has been disconnected.
I asked the same question to Brad Wilson/Marcin Dobosz/Damien Edwards at aspconf, and Damien suggested using HttpContext.Current.Response.IsClientConnected - so basically bypassing Web API and obtaining the connectivity info from the underlying host directly (however there is still a race condition involved anyway). That is really .NET 4. He also pointed an interesting way in which this problem could be avoided in .NET 4.5 using an async cancellation token. Frankly, I have never got around to test it, but perhaps this is something you should explore.
You can see their response to this problem in this video - http://channel9.msdn.com/Events/aspConf/aspConf/Ask-The-Experts - fast forward to 48:00