Is it possible to play a sound when a notification is received? - push-notification

I'm investigating implementing push notifications in my solution, and I'd like to play an application-specific sound when I receive a notification.
I've been using the following sample as a guide: http://code.msdn.microsoft.com/windowsapps/push-and-periodic-de225603
I've added pushNotification as a Background Task in the app manifest:
<Extensions>
<Extension Category="windows.backgroundTasks" EntryPoint="PushNotificationsHelper.MaintenanceTask">
<BackgroundTasks>
<Task Type="systemEvent" />
<Task Type="pushNotification"/>
</BackgroundTasks>
</Extension>
</Extensions>
and MaintenanceTask is defined as:
namespace PushNotificationsHelper
{
public sealed class MaintenanceTask : IBackgroundTask
{
public void Run(IBackgroundTaskInstance taskInstance)
{
Notifier notifier = new Notifier();
notifier.RenewAllAsync(false).AsTask().Wait();
// here I can execute my code to locate the sound in my solution and play it
}
}
}
It would be ideal for this Run method to execute and then let me play a sound.
However, I can't get the run method to fire when I'm testing with the Windows Phone emulator's Notification Tool.
What do I need to do to get this to run? Is there a different way for me to play sounds associated with my app?

Related

Event Handler for A Rebus Topic

As we know that Rebus provides Topic Based routing in addition to the familiar TypeBased routing although we are told that the TypeBased routing follows the same principle.
On my side however unfortunately I have not seen a good example on how to create a handler that processes messages published to a particular topic.
Suppose I publish my message as follows
var message=new Student { StudentID=90008,FirstName="Chilipo",LastName="Mjengo" };
await bus.Advanced.Topics.Publish("rebus_example_topic", message);
In another endpoint I have subscribed to the topic as follows
await bus.Advanced.Topics.Subscribe("rebus_example_topic");
My interest is to know how do I then implement the Handler that will process the messages published to the rebus_example_topic.
Regards
It's quite simple, actually 🙂 the preferred way of writing message handlers is to implement IHandleMessage<TMessage>, where TMessage is your message type.
In your case that would be
public class StudentHandler : IHandleMessages<Student>
{
public async Task Handle(Student message)
{
// handle your message in here
}
}
How you then activate your message handler depends on which handler activator, you're using. The "handler activator" is what you use to instantiate message handlers, so you just need to register your handler in that to make it available to Rebus.
Some container integrations even come with additional help in the form of registration extensions, so e.g. if you're using Autofac, you can register your handler like this:
containerBuilder.RegisterHandler<StudentHandler>();

Appcenter push: dynamic navigation based on custom data

I'm wondering if I could get some help using AppCenter push in my Xamarin Forms app that targets Android & iOS.
Essentially, I've followed the instructions and I'm able to see the push notifications in my testing on Android. I understand that there are different behaviors between foreground and background notifications and have stepped through via the debugger when the PushNotificationReceived event happens..
The issue I'm having is I cannot find a reliable way to isolate when a user is entering the app because they tapped on a notification when the app is not loaded.
In my App.xaml.cs, I have the following:
protected override async void OnInitialized()
{
InitializeComponent();
Push.PushNotificationReceived += Push_PushNotificationReceived;
AppCenter.Start("ios={ios ID}" +
"uwp={Your UWP App secret here};" +
"android={android ID}",
typeof(Analytics), typeof(Crashes), typeof(Push));
await NavigationService.NavigateAsync("Splash"); // this is my splash screen that shows
}
private async void Push_PushNotificationReceived(object sender, PushNotificationReceivedEventArgs e)
{
if (e.CustomData != null)
{
if (e.CustomData.ContainsKey("roundId"))
{
string roundId = e.CustomData["roundId"];
//I want to navigate directly to this UI
await NavigationService.NavigateAsync($"IconNavigationPage/HomeView/Round?roundId={roundId}");
}
}
}
So, as you can see, under normal circumstances, the app will load the Splash view which does some loading, and redirects to a home view. When the notification is received and the user has the app running in the background, on Android, it's working fine. I changed my launch mode to SingleTop and added the following to my MainActivity.cs
protected override void OnNewIntent(Android.Content.Intent intent)
{
base.OnNewIntent(intent);
Push.CheckLaunchedFromNotification(this, intent);
}
The issue is, when the app is not running in the background, and I tap the notification, the Splash screen navigation call is called, then my navigation call in the PushNotificationReceived event. This essentially causes the app to load the UI that is defined in the event, for a second, then Splash UI redirects happen. This is due to the fact that OnInitialize() gets ran when the app is loaded from the Tap of the notification, when the app is not running in the background.
I have experimented in trying to implement the PushNotificationReceived event handler in the Android MainActivity.cs file, and I do see that this fires before the same PushNotificationReceived event handlers in the Shared project. Unfortunately it runs after the call to the LoadApplication, so my shared project's OnInitialize() gets fired first (which has that navigation call to Splash)
I guess what I'm looking for is some guidance, or maybe a point to a tutorial, on how I can accomplish notifying the Shared project's OnInitialize not to do the standard navigation to Splash, but rather do the navigation necessary for the Push Notification instead. I've search high and low, but all of tutorials / docs simply do a debug write to console proving that that the custom data that was passed is there, which I too can see, I cannot find anything that handles real-world use cases of a viable workflow to control navigation based on the tap of a notification.
Any help or guidance would be greatly appreciated.
Thank-you in advance.

spring-mvc, websockets push integration

I've followed this link http://spring.io/guides/gs/messaging-stomp-websocket/ and got the app up and running.
What I wanted was a little more than that, I wanted to to be able to push the data back to the client without the client having to send any thing.
So I've setup a long running task with a listener similar to the below
GreetingController implements RunnableListener
and the RunnableListener has a method
public Greeting greeting(HelloMessage message);
The implementation of the method is to kick off a thread and then call the listener method..
I see the output on the console when that happens, but I don't see anything on the browser.
Could anyone please show me how to kick off a running task and let the server push the content to the browser using Spring instead of poll (setTimeout stuff in javascript?)
Regards
Tin
What is this RunnableListener interface?
What is triggering this task - is it scheduled regularly?
Once the client has subscribed to a given topic (here, /topic/greetings), you can send messages to that topic whenever you want using a MessagingTemplate. For example, you could schedule this task and let it send messages regularly on a given topic:
#Service
public class GreetingService {
private SimpMessagingTemplate template;
#Autowired
public GreetingService(SimpMessagingTemplate template) {
this.template = template;
}
#Scheduled(fixedDelay=10000)
public void greet() {
this.template.convertAndSend("/topic/greetings", "Hello");
}
}
Check out the reference documentation for more details.

Hooking into 3rd Party Web Service (WCF) calls

At my workplace we are in the process of upgrading our Time and Attendance setup. Currently, we have physical terminals that employees use to check in and check out. These terminal communicate to a 3rd party T&A system via web service calls.
About the T&A web service:
Hosted on IIS 6
Communication is with WCF over HTTP
We're only interested in one of the exposed methods (let's call it Beep())
What I need to do:
Leave the original T&A system in place, untouched
Write a custom service that also reacts to calls to Beep()
So, essentially, I need to piggy-back on all the calls to Beep(), but I'm not sure what the best approach is.
What has been considered already:
Write a custom webservice that implements the exact same same contract as the T&A service and direct all the terminals to that custom service. The idea being that I can then invoke the original T&A service from my custom service, as well as applying any other logic required.
This seems overly invasive to me, and seems needlessly risky. We want to leave the original system as unmodified as possible.
Write a custom HTTP Handler to intercept calls to the original T&A service.
We've actually already done something like this in house, but our implementation takes the original HttpRequest, extracts the contents, invokes a custom service, and finally create a new HttpRequest based on the original request so that the original web service call to Beep() is made.
What I don't like about this approach is that the original HttpRequest is lost. Yes, a second, supposedly identical, request is created, but I don't know enough about HttpRequests to guarantee this is safe.
I prefer option 2, but it's still not perfect. Ideally we wouldn't need to destroy the original HttpRequest. Does anyone know if this is possible?
If not, can anyone suggest another way of doing this? Can IIS be configured to fork requests to two destinations?
Thanks
UPDATE #1
I have found a solution (documented here), but I'm still open to other options.
UPDATE #2
I like flup's solution (and justification). He gets the bounty :) Thanks flup!
You can configure the web service to use a custom operation invoker, an IOperationInvoker.
WCF deserializes the original HTTP request as always, but instead of calling Beep() on the existing web service class, it will call your invoker instead. The invoker does its special thing, and then calls Beep() on the original service.
Advantage over implementing an IHTTPModule would be that all things HTTP are still handled by the original web service's configuration, unchanged. You fork off at a higher level of abstraction, namely on the web service's interface, at the Beep() method.
The nitty gritty of setting up a custom operation invoker without changing the existing service class (which makes it harder):
Implement a custom IOperationBehavior which sets the custom IOperationInvoker on the service's Beep() method in its ApplyDispatchBehavior method.
Implement a custom IEndpointBehavior which sets the custom IOperationBehavior in its ApplyDispatchBehavior method.
Put these two behaviors, with your IOperationInvoker, in a class library and add it to the existing service
Then configure the service to use the IEndpointBehavior.
See When and where to set a custom IOperationInvoker? and http://blogs.msdn.com/b/carlosfigueira/archive/2011/05/17/wcf-extensibility-ioperationinvoker.aspx for the invoker bit.
See Custom Endpoint Behavior using Standard webHttpEndpoint on how to configure a custom endpoint.
Sounds actually like you want to integrate your system into an ESB pattern. Now the MS solution to the ESB problem is Biztalk. Biztalk is the thermonuclear warhead nut cracker in this case. You don't want Biztalk.
Check out the results here for lightweight alternatives
I have found a solution using a custom IHttpModule. See sample below:
using System;
using System.Text;
using System.Web;
namespace ForkHandles
{
public class ForkHandler : IHttpModule
{
public void Init(HttpApplication application)
{
application.BeginRequest += new EventHandler(application_BeginRequest);
}
void application_BeginRequest(object sender, EventArgs e)
{
var request = ((HttpApplication)sender).Request;
var bytes = new byte[request.InputStream.Length];
request.InputStream.Read(bytes, 0, bytes.Length);
request.InputStream.Position = 0;
var requestContent = Encoding.ASCII.GetString(bytes);
// vvv
// Apply my custom logic here, using the requestContent as input.
// ^^^
}
public void Dispose()
{
}
}
}
This will allow me to inspect the contents of a webservice request and react to it accordingly.
I'm open to other solutions that may be less invasive as this one will require changing the deployed 3rd party web service's configuration.
If you want to intercept the message to the T&A WCF service i would suggest using custom listener which can be plugged into the service call by making changes in the web.cofig.
This will be transparent.
Please look for WCF Extensibility – Message Inspectors.
system.diagnostics>
<sources>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="ServiceModelMessageLoggingListener">
<filter type=""/>
</add>
</listeners>
</source>
</sources>
</system.diagnostics>

WebTest for SignalR possible?

if I send a request, and I expect the response to come trough SignalR, is it possible to test this using a LoadTest or PerformanceTest in Visual Studio?
Short answer: Yes
I've done this several times in CodedWebTests but it would also be possible to do in a declarative WebTest. You can use a custom PreWebTest Event Handler to create your signalR client and connect to your SignalR hub. What you choose to do with the signalR notification is up to you but I like to save it to the WebTestContext as well as display it on the test results screen using the AddCommentToResult method.
The method below creates a hubConnection invokes the "addToGroup" function on the hub and then tells the client what to do when it receives a message.
using Microsoft.AspNet.SignalR.Client;
public class SignalRPlugin : WebtTestPlugin
{
public override void PreWebTest(object sender, PreWebTestEventArgs e)
{
var hubConnection = new HubConnection("yourSignalRUrl");
var hubProxy = hubConnection.CreateHubProxy("notifications");
hubConnection.Start().Wait();
hubProxy.Invoke("addToGroup", "me");
hubProxy.On<string>("message", s =>
{
e.Webtest.AddCommentToResult(s);
e.Webtest.Context.Add("signalRMessages", s);
});
}
}
Use it by attaching the event handler in your test constructor.
public MyWebTest()
{
PreWebTest += new SignalRPlugin().PreWebTest;
}
Then once you have the signalR messages you can use a custom validation rule to validate that the response was received. Just have a while loop checking the WebTestContext for the "signalRMessages" key. I strongly suggest making sure you add a timeout feature so you are not waiting forever if the messages never come in.
The other option if you are writing CodedWebTests is to create a WaitForNotifications method that basically does the same thing as the validation rule. The advantage with this is that you can use an extraction rule to get data out of the last response and then use that data in validating your signalR messages. If you still need to fail a test in your WaitForNotification method use WebTest.InternalSetOutcome(Outcome.Fail);
The best way to load test a SignalR application is by building on the crank project included in the source.
This is a simple ramp up solution built with the .Net client but it is relatively easy to modify to call whatever hub methods you require and to analyse the responses.
You can always attach the Visual Studio profiler to your iis express instance to get detailed profiling data if required.

Resources