Windows Phone 8 push notification push channel always creates new channel uri - c#

I wanted to check that my push notification implementation is correct.
Each time I open my app (in actual fact I register the push channel only on a specific page so it's each time I go back and forth from that page) a new push channel URI is created which I store in my mobile services database to send push notifications to. This doesn't seem correct to me as each time the app/page is opened a new push channel URI is generated and so the list of channel URIs just grows and grows for each device that uses my app. I'd assume that you create a push channel, store the channel URI and push to it as needed. I will make note here that I am using raw push notifications.
I understand that push channels will expire every so often but for me it's occurring each time I back out of the app/page and therefore when onNavigateTo is called I find the push channel which does exist and a new channel URI is always created. Is this correct?
My code is as follows:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
registerPushChannel();
}
private void registerPushChannel()
{
// The name of our push channel.
string channelName = "RawSampleChannel";
// 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);
// code which passes the new channel URI back to my web service
}
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
pushChannel.Close();
}
So to clarify, the app is opened and the push channel is registered and the channel uri is saved in my web service. The web service then sends notifications to the channel uri. When I exit the app or page and return to it, the push channel is found but a new channel uri is created which I again save to my web service. My channels table in effect just keeps growing and growing.
So is this the way it should work with new channel URIs continually generated? It kind of doesn't make sense to me. I'm not sure how toast and tile notifications work but I'd assume the channel URI needs to be static when the app closes to keep receiving notifications while the app is closed, but perhaps that could be a functionality of bindtotoast and bindtotile and so what I'm doing is correct because it's to do with raw notifications.

You're mostly doing it right.
Push Notifications are a funny thing.
You create a channel, send it to your server and then the server can send until it fails (the channel Uri expires or there's an error).
At which point the app needs to create a new ChannelUri and then UPDATE the value stored for that app/device on the server. The server will then be able to send notifications.
Some important points
When a new channel Uri is requested for one that is still valid you'll get the same one back.
When your ask for a new channel uri and the current one has expired, you'll normally get the same uri returned but the channel will be made live again.
There is no way to know if a channel has expired from within an app without running code like your registerPushChannel method. (Unless you track this on your backend and the app queries the backend.)
There is no way to tell the app that a channel has expired, or tell the user to reopen the app to re-establish a channel connection using the push infrastructure.
The standard way to try and ensure that the channel is always available is to check the channel whenever the app is started.
This is what you're doing, you probably just want to make sure you're updating server records not just adding more.

Related

Azure Service Bus send message every other time

I've a c# dotnet webjob and a simple desktop app.
Sending a message apperaes to work only every other time.
serviceBusClient = new QueueClient(_config["ServiceBusConnectionString"], "queuename", ReceiveMode.ReceiveAndDelete);
await serviceBusClient.SendMigrationMessageAsync("1", label);
await serviceBusClient.SendMigrationMessageAsync("2", label);
await serviceBusClient.SendMigrationMessageAsync("3", label);
await serviceBusClient.SendMigrationMessageAsync("4", label);
SendMigrationMessageAsync is an extension:
public static async Task SendMigrationMessageAsync(this IQueueClient client, string messageText, string label)
{
Message message = new Message(Encoding.UTF8.GetBytes(messageText));
message.Label = label;
await client.SendAsync(message);
}
In the destkop app I registered to receive the message and also registered a message exception handler (which is not call at all).
In this scenario I can only receive message "2" and "4".
When I stopped execution after the first message had been sent, the message never showed up on the Azure service.
Thanks in advance
EDITED:
I found out that arter creating brand new Azure Service Bus Namespace, all is working fine.
I had basic pricing tier and even after upgrading to standard I was able to only send every other message.
Creating new service sorted this out.
Is there any limitation or throtling? I haven't sent many messages at all, something around 300 daily.
You most probably had two processes with the same subscription id, so they are "stealing" messages from each other. Let's say there are two console apps, the first one sending messages and the second one receiving.
With both having same subscription id it looks like this:
And with the unique subscription for each process everything is ok:

Shifting from chatbot view to ionic mobile app page automatically when reaching a step in dialogue flow

I am using MS chatbot-framework V3 and embedding it in my ionic 3 mobile app via Direct line.
What I am aiming to is when reaching the end of conversation, the chatbot is terminated and shifting to another page in the mobile app with passing some values from chatbot to that page.
When you reach the end of your conversation, you can send an event activity to your DirectLine Client with channel data from the conversation, and once the client receives the event, you can transition to the next view in your app with the channel data. See the code snippets below.
Sending Transition Event
In the bot, we are going to send back channel events to DirectLine with the data we have gathered in the chat. Basically, you just need to send an activity with the type property set to 'event' and the name attribute set to some string value - we are going to use 'transition' in this case. The conversation data is going to be encapsulated in the activity's channel data.
// End of conversation
var reply = turnContext.Activity.CreateReply();
reply.Name = "transition";
reply.Type = "event";
reply.ChannelData = JObject.FromObject( new {
user = new {
name = "TJ",
location = "Seattle"
}
});
await turnContext.SendActivityAsync(reply, cancellationToken: cancellationToken);
Listen for Transition Event
On the client side, we are going to filter the incoming activities to listen for our 'transition' event from the bot. When it's received, you can transition to the next view and pass along the channel data which contains the conversation data.
import { DirectLine } from 'botframework-directlinejs';
var directLine = new DirectLine({
secret: "<DIRECTLINE_SECRET"
});
directLine.activity$
.filter(activity => activity.type === 'event' && activity.name === 'transition')
.subscribe( activity => { /* Initiate transition to next view with activity.channelData */ });
Hope this helps!

PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync duplicate channel

We use Azure Notifications Hub to manage notifications registrations. Every time user launches application, we call PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync and then RegisterNativeAsync of NotificationHub to register channel uri, returned by first with some tags like "Username" and "InstallId" - that is unique per app installation. Then from back-end we send notifications using these tags.
But we have noticed problem - when user hard-resets device, the previous channel registration stays active in notification hub. In that case user receives duplicate notifications by his "Username" tag. "InstallId" doesn't help in that case, as it is changing with new app installation.
We have thought about managing channels server-side. But that will not solve the problem.
Maybe anyone has some suggested work-around?
Also, we don't know what information does PushNotificationChannelManager use when creating new or returning existing channel? Does it use some device information?
I think you can send the backend the device unique Id along with the installation Id. The device id will not change upon hard reset.
private string GetDeviceUniqueID()
{
HardwareToken token = HardwareIdentification.GetPackageSpecificToken(null);
IBuffer hardwareId = token.Id;
HashAlgorithmProvider hasher = HashAlgorithmProvider.OpenAlgorithm("MD5");
IBuffer hashed = hasher.HashData(hardwareId);
string hashedString = CryptographicBuffer.EncodeToHexString(hashed);
return hashedString;
}

Get all events from Asterisk 12

In my application I want to show a real time overview of all active calls on a asterisk server.
That's why I want to get all events (channel created/destroyed etc.) from Asterisk 12 server using the Asterisk 12 REST API (ARI).
When I connect to the websocket I only get events that are somehow targeted to my application that I specified in the initial call to "/ari/events" (in this case "hello").
$ wscat.py 'ws://localhost:8088/ari/events?app=hello&api_key=...'
How can I get all events (e.g. also information about new incoming calls)?
Or is there another possibility to get the desired information?
I am using AsterNET.ARI .NET Stasis Framework and the following code:
// Create a message client to receive events on
Client = new ARIClient(
new StasisEndpoint(Host, Port, Username, Password),
AppName
);
Client.Connect();
Client.OnChannelStateChangeEvent += Client_OnChannelStateChangeEvent;
The method Client_OnChannelStateChangeEvent is only called for calls that I have originated by my application using Client.Channels.Originate(...).
You can use AMI(manager interface)
http://www.voip-info.org/wiki/view/Asterisk+manager+API
http://www.voip-info.org/wiki/view/asterisk+manager+events

Keep WebSocket and some event handlers alive while app is active

I use Caliburn.Micro to build a Windows 8.1 Universal app. The app connects to a web service using a WebSocket. I would like this connection, once established, to be kept alive as long as the app is active, no matter what page the user is on.
Currently I'm doing it like this:
container = new WinRTContainer();
container.Singleton<IConnectionService, ConnectionService>();
and it seems to work as I want to. I can inject it in my viewmodels and the connection is still open and it does receive messages even when a view model that does not inject the service is active. I am however a bit curious if this is the correct way (and if it's actually doing what I'm expecting)?
Secondly, I'm using the connection manager to parse the JSON returned from the WebSocket connection and creating corresponding classes like RandomThingHappened and broadcasting these using the event aggregator service from Caliburn.Micro. View interested in these can subscribe and do what they want. However, there are some messages that I would like handled regardless of which view the user is on. Is this possible? I've thought about creating singletons for this as well, and just make sure to instantiate these somewhere. That does however seem a bit... risky.
Suggestions?
Not really sure about websocket but
I am using the following ways for My WCF service ( the dumb terminal must be always connected cause the WCF service will push message to connected terminal using callback
[OperationContract(IsOneWay = true)]
void KeepConnection();
and in your client use a timer to keep calling the service
var timer = new DispatcherTimer { Interval = new TimeSpan(0, 0, 50) };
timer.Start();
timer.Tick += (sender, args) =>
{
try
{
if (this.client.State == CommunicationState.Faulted)
{
this.RegisterTerminal();
}
this.client.KeepConnection();
}
catch
{
throw new Exception("Failed to establish connection with server");
}
};
As for the broadcasting you can use EventAggregator to publish your event to all the listening class.
you can read it more here Event Aggregator

Categories