HTTPWebRequest Wakes Up WIFI? - c#

I have a rather simple question.
We use BackgroundAgents( Periodic agents ) to perform some background tasks which require WiFi(Internet) connectivity in order to perform an HttpWebRequest. As mention in the second reference HttpWebRequest is supported but the problem is that if the Windows Phone is locked or idle for more than 1 minute the WiFi is disabled.
I have two important questions based on what I have read and tried until know:
Does Microsoft periodically enables WiFi according to predefined intervals to check for new emails or other notifications? If the answer is yes will my background agent rescheduled and run during this interval?
Until know I found that HttpWebRequest does not wakes the phone if locked or if is idle for more than 1 minute. Is that the case? A lot of people state that HttpWebRequest works fine if the phone is locked or if the 1 minutes has passed. I was not able to do that.
Thanks.
Sample Code:
protected override void OnInvoke(ScheduledTask task)
{
ScheduledActionService.LaunchForTest(task.Name, TimeSpan.FromSeconds(120));
MakeHttpRequest("test");
}
private void MakeHttpRequest(string position)
{
if (position != null)
{
var request = (HttpWebRequest)WebRequest.Create(
new Uri("http://mydomain.com/Testing/Details/"+position));
request.BeginGetResponse(r =>
{
var httpRequest = (HttpWebRequest)r.AsyncState;
var httpResponse = (HttpWebResponse)httpRequest.EndGetResponse(r);
using (var reader = new StreamReader(httpResponse.GetResponseStream()))
{
var response = reader.ReadToEnd();
Deployment.Current.Dispatcher.BeginInvoke(new Action(() =>
{
}));
}
}, request);
}
this.NotifyComplete();
}
PS: Please keep in mind that when I run this code while the application is connected to the computer using a USB cable everything runs fine. That's why I believe its a problem with the background worker which does not wake the phone + WiFi in order to perform tha HttpWebRequest.

It is my experience with using the phone on a day-to-day basis that Windows Phone does not reenable wifi after it locks unless the phone is plugged in and charging. It also allows data transfers that were already started to complete before disabling the wifi.
However, even if the phone tried to reconnect periodically, some wifi providers redirect to an authentication page for authentication every time the user reconnects and Windows Phone does not handle that situation.
In reality, there's no guarantee that you have data services available as the user walks around with the phone, so handling the issue should be part of a normal path for the application code.

Related

How do I run this method in timer even after the app is closed in Xamarin form?

I have a method on the sample content page (sample.XAML.cs) and I want to set this method in a timer and run every 10 seconds even after the app is killed or closed.
public async void AlarmStart()
{
HttpClient client = new HttpClient();
HttpResponseMessage response = client.GetAsync("JsonFile").Result;
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<List<OnlineValueClass>>(content);
}
}
In Android, starting in Android 8.0 (API level 26), an Android application no longer have the ability to run freely in the background. For more details about this, you can refer to Background Execution Limits in Android 8.0:
But you can try to restarted the service once it been finished by a BroadcastReceiver . The function of BroadcastReceiver is to receive a signal when someone or something kills the service; its role is to restart the service.
For more details, you can check an relative article by entering key words
Creating a never ending background service in Android. Though it's Java code, it's easy to understand and convert

How to check internet availability during single frame?

In Unity3D, is there any way to instantly check network availability? By "instantly", I mean during a single frame, because lines of code below this check need to work based on network availability.
It all happens during Start(). I know I can ping a web page, and get network availability based on any errors occurring during the download of a web page. However, an operation like this takes several seconds whereas I need to know the result immediately, before moving to next line of code in the script.
Assuming your game is running at reasonable frame rates 30fps or greater then any solution that you can come up with (even pinging the host of your server) will only be valid for instances where the latency of the round trip is less than 1/30th of a second or lower ( roughly 30 ms)
As such it is unrealistic to handle this between frames (except for maybe on local networks)
Instead i would suggest into looking into threading your network based code to decouple it from frames
Don't do this.
As long as you do not provide more information of what exactly you are planning, one cannot give you proper answers.
This is unsatisfying for both sides.
But what you actually could do:
Open a TCP connection to a web available device like the google.com server.
Once the network state is changed (connected, disconnected, ...) trigger a simple c# event or set a variable like isOnline = true;.
This can be a way. But it is a bad one.
It all happens during Start()
Yes, this is possible and can be done in one frame if this is the case. I would have discouraged it so much if this operation is performed every frame in the Update function but that's not the case. If this is done in the beginning of the app, that's fine. If you do this while the game is running, you will affect the performace.
but operation like this take several seconds
This is designed like this in order to avoid blocking the main Thread.
Network operation should be done in a Thread or with the async methods to avoid blocking the main Thread. This is how most Unity network API such as the WWW and UnityWebRequest work. They use Thread in the background and then give you coroutine to manage that Thread by yielding/waiting in a coroutine function over frames until the network request completes.
To accomplish this in one frame just use HttpWebRequest and provide a server url to check. Most examples uses the google.com since that's always online but make sure to provide "User-Agent" so that the connection is not rejected on mobile devices. Finally, if HttpStatusCode is not 200 or if there is an exception then there is a problem, otherwise assume it is connected.
bool isOnline()
{
bool success = true;
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://google.com");
request.Method = "GET";
//Make sure Google don't reject you when called on mobile device (Android)
request.changeSysTemHeader("User-Agent", "Mozilla / 5.0(Windows NT 10.0; WOW64) AppleWebKit / 537.36(KHTML, like Gecko) Chrome / 55.0.2883.87 Safari / 537.36");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (response == null)
{
success = false;
}
if (response != null && response.StatusCode != HttpStatusCode.OK)
{
success = false;
}
}
catch (Exception)
{
success = false;
}
return success;
}
Class for the custom changeSysTemHeader function used to change the User-Agent:
public static class ExtensionMethods
{
public static void changeSysTemHeader(this HttpWebRequest request, string key, string value)
{
WebHeaderCollection wHeader = new WebHeaderCollection();
wHeader[key] = value;
FieldInfo fildInfo = request.GetType().GetField("webHeaders",
System.Reflection.BindingFlags.NonPublic
| System.Reflection.BindingFlags.Instance
| System.Reflection.BindingFlags.GetField);
fildInfo.SetValue(request, wHeader);
}
}
Simple usage from the Start function done in one frame:
void Start()
{
Debug.Log(isOnline());
}

Creating a push or background service that checks remote server

General idea of what I need:
I am porting an Android app to iOS (Using Xamarin, but I can translate to C# from objective C easily enough) that relies heavily on the AlarmManager to do background checks on an HTML page on a website that I don't own. AlarmManager is essentially a task scheduler for Android. The user would set the frequency to whatever they desired.
What I've tried:
Background fetching:
app.SetMinimumBackgroundFetchInterval(240);
UNUserNotificationCenter.Current.RequestAuthorization(UNAuthorizationOptions.Alert, (approved, err) =>
{
// Handle approval
});
UNUserNotificationCenter.Current.Delegate = new WEBSITEFUNCTIONS.UserNotificationCenterDelegate();
return base.FinishedLaunching(app, options);
public override void PerformFetch(UIApplication application, Action<UIBackgroundFetchResult> completionHandler)
{
System.Diagnostics.Debug.WriteLine("interval");
WEBSITEFUNCTIONS kf = new WEBSITEFUNCTIONS();
kf.doCheck();
completionHandler(UIBackgroundFetchResult.NewData);
}
Perform Fetch is just straight up NEVER called. I need some consistency (being one minute off is no big deal... but several hours will not do). I let it run and it just straight up never worked. I've read lots on how PerformFetch works, and I don't think it'll give me the critical response time that the user needs.
UserNotifications:
New to iOS 10, is the ability to have repeating notifications. However this repeats the same notification.
var trigger = UNTimeIntervalNotificationTrigger.CreateTrigger(60, true);
var requestID = "sampleRequest";
var request = UNNotificationRequest.FromIdentifier(requestID, content, trigger);
UNUserNotificationCenter.Current.AddNotificationRequest(request, (err) =>
{
if (err != null)
{
// Do something with error...
}
});
Push Alerts:
My own server
I could setup a server that does the checking and then sends a message to the Firebase Cloud Messaging to send a message to the user about the new items. I have approximately 500 active users on the Android version, if they check 5 different pages every 5 minutes, at 90 kbs a check, that's about half a gig of bandwidth an hour.
So the cons are:
Excessive bandwidth usage will make my home internet
a lot slower
I will need to secure it myself
Power outages can sometimes last for days, leaving end users out of the loop
Their server could boot off my machine at any given
moment, I could get a new IP address from my ISP if that happened... assuming they allow that
Using my shared hosting, setup a cronjob every 15 minutes
I can setup a cronjob to do an alert every 15 minutes. It's not the fastest, but way better than relying on the first option (as it just straight up never gets called)
Once again, I'm at the mercy that their server doesn't kick me off. The app completely breaks if they do this.
Shared hosting might cut me off for putting too much strain on their servers (Hostgator claims unlimited bandwidth, I'm not sure if they'd like me doing that)

Is there such a RTSP Ping?

I am currently working on a WinForm app to stream videos from IP camera using the RTSP protocol in C#. Everything worked fine. Part of the requirement for the app includes a function to check whether the IP camera is online or not.
So I did a ping function using the System.Net.NetworkInformation.Ping class to ping the IP camera. Say if the RTSP url of the camera is as follows rtsp://[CAMERA IP]:554/Master0-RTSP/1.0, I would only need to extract the [CAMERA IP] part and use the Ping class to see if the camera is online or not by using its IP.
Initially, it works until an issue came, say if one to enter an IP which may not be the intended IP Camera (say an IP of a computer) the ping function would still work if the entered IP of the entered device is online.
I tried to search for something like a RTSP ping but could not find one. Was hoping for any advices or opinions on this matter. Any example in C# are greatly appreciated. Thank you for your kind attention.
OPTIONS can possibly work but the standard specifies the correct way is through using theGET_PARAMETER.
RFC2326 outlines that clearly
http://www.ietf.org/rfc/rfc2326.txt
10.8 GET_PARAMETER
The GET_PARAMETER request retrieves the value of a parameter of a
presentation or stream specified in the URI. The content of the reply
and response is left to the implementation. GET_PARAMETER with no
entity body may be used to test client or server liveness ("ping").
While GET_PARAMETER may not be supported by the server there is no way to tell how that server will react to the OPTIONS request which does not even require a sessionID. Therefor it cannot be guaranteed it will keep your existing session alive.
This is clear from reading the same RFC about the OPTIONS request
10.1 OPTIONS
The behavior is equivalent to that described in [H9.2]. An OPTIONS
request may be issued at any time, e.g., if the client is about to
try a nonstandard request. It does not influence server state.
Example:
C->S: OPTIONS * RTSP/1.0
CSeq: 1
Require: implicit-play
Proxy-Require: gzipped-messages
S->C: RTSP/1.0 200 OK
CSeq: 1
Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE
Note that these are necessarily fictional features (one would hope
that we would not purposefully overlook a truly useful feature just
so that we could have a strong example in this section).
If GET_PARAMETER is not supported then you would issue a PLAY request with the SessionId of the session you want to keep alive.
This should work even if OPTIONS doesn't as PLAY honors the Session ID and if you are already playing there is no adverse effect.
For the C# RtspClient see my project # https://net7mma.codeplex.com/
And the article on CodeProject # http://www.codeproject.com/Articles/507218/Managed-Media-Aggregation-using-Rtsp-and-Rtp
Regarding RTSP in C# see this thread Using RTMP or RTSP protocol in C#
Regarding Ping ... you can implement is as DESCRIBE operation ... but pay attention do not make it too frequently, the device should be affected.
http://www.ietf.org/rfc/rfc2326.txt
Instead of ICMP ping, you might want to keep a helper RTSP session without video/audio RTP streams, checking good standing of socket connection and sending OPTIONS or DESCRIBE command on a regular basis, e.g. once a minute, in order to see if the device is responsive.
Some suggest using GET_PARAMETER instead of options, however this is inferior method. OPTIONS is mandatory, GET_PARAMETER is not. Both serve different purpose. Both have small server side execution expense. OPTIONS is clearly the better of the two.
Some servers may not support setting stream parameters and thus not support GET_PARAMETER and SET_PARAMETER.
You can use RTSPClientSharp and do something like this:
public static async Task TestRTSPConnection(string rtspAddress, string user, string password)
{
var serverUri = new Uri(rtspAddress);
var credentials = new NetworkCredential(user, password);
var connectionParameters = new ConnectionParameters(serverUri, credentials);
var cancellationTokenSource = new CancellationTokenSource();
var connectTask = ConnectAsync(connectionParameters, cancellationTokenSource.Token);
if (await Task.WhenAny(connectTask, Task.Delay(15000 /*timeout*/)) == connectTask)
{
if (!connectTask.Result)
{
logger.Warn("Connection refused - check username and password");
}
logger.Info("Connection test completed");
}
else
{
logger.Warn("Connection timed out - check username and password");
}
}
private static async Task<bool> ConnectAsync(ConnectionParameters connectionParameters, CancellationToken token)
{
try
{
using (var rtspClient = new RtspClient(connectionParameters))
{
rtspClient.FrameReceived +=
(sender, frame) => logger.Info($"New frame {frame.Timestamp}: {frame.GetType().Name}");
while (true)
{
logger.Info("Connecting...");
try
{
await rtspClient.ConnectAsync(token);
}
catch (OperationCanceledException)
{
logger.Info("Finishing test before connection could be established. Check credentials");
return false;
}
catch (RtspClientException e)
{
logger.Error($"{e.Message}: {e.InnerException?.Message}");
return false;
}
logger.Info("Connected - camera is online");
return true;
}
}
}
catch (OperationCanceledException)
{
return false;
}
}
It works for me pretty well if you just care about pinging and if the camera is online or not. Also timeout happens when credentials are incorrect. You get direct failure if port is not exposed or connection is refused.

How to programmatically detect when the OS (Windows) is waking up or going to sleep

Background
My son likes to use his laptop when he's not supposed to and I just thought it would be handy if I could write an application that would email me whenever he opened / closed his laptop.
(I'd even settle for something that notified me when there was network traffic on the machine)
Question
How do you programmatically detect when an OS is waking up or going to sleep? I found this link from this related post. But that covers OS X. I'm looking for the same thing for Windows 7.
(I'd like to do this in Java, if possible, but I'd settle for C#/C++)
Easiest way is not to write any code at all, even though this is stack overflow. Click Start, type Schedule and choose Scheduled Tasks. Set one up (click Create Task) and set a Trigger when the machine is unlocked. For the Action, have it send you an email.
Repeat for startup and when a user logs in, if you want. Done.
You're going to want to create a window and watch for the WM_POWERBROADCAST message (http://msdn.microsoft.com/en-us/library/aa373248%28v=vs.85%29.aspx) and check the wParam for your desired action. For example, your window should receive a WM_POWERBROADCAST with PBT_APMSUSPEND as the wParam when the system is about to enter a suspended state (i.e. closing a laptop). Resuming seems to have a few different wParam values: PBT_APMRESUMESUSPEND, PBT_APMRESUMECRITICAL and PBT_APMRESUMEAUTOMATIC
I search for a long time and found that this was the best way, the 'Sleep'-event was never working before:
private ManagementEventWatcher managementEventWatcher;
private readonly Dictionary<string, string> powerValues = new Dictionary<string, string>
{
{"4", "Entering Suspend"},
{"7", "Resume from Suspend"},
{"10", "Power Status Change"},
{"11", "OEM Event"},
{"18", "Resume Automatic"}
};
public void InitPowerEvents()
{
var q = new WqlEventQuery();
var scope = new ManagementScope("root\\CIMV2");
q.EventClassName = "Win32_PowerManagementEvent";
managementEventWatcher = new ManagementEventWatcher(scope, q);
managementEventWatcher.EventArrived += PowerEventArrive;
managementEventWatcher.Start();
}
private void PowerEventArrive(object sender, EventArrivedEventArgs e)
{
foreach (PropertyData pd in e.NewEvent.Properties)
{
if (pd == null || pd.Value == null) continue;
var name = powerValues.ContainsKey(pd.Value.ToString())
? powerValues[pd.Value.ToString()]
: pd.Value.ToString();
Console.WriteLine("PowerEvent:"+name);
}
}
public void Stop()
{
managementEventWatcher.Stop();
}
A very simple, perhaps crude, but effective way may be to have a program with a timer firing every minute. If the timer fires and it's been, say, 5 minutes of real time since its last execution then you can likely assume that the computer was sleeping since it's unlikely that your thread was unable to be scheduled for so long.
The other reason for the difference may be a clock adjustment, like DST or a manual change, but that kind of "noise" should be very low, in your scenario.
You could write a simple app and register it as a Windows service, to be started automatically at system startup. This app could then do whatever you want when it starts. And if it's a proper Windows app, it can register to get notification about impending system shutdown too (I don't remember the details but I implemented this in a C++ MFC app many years ago).
If you prefer Java, you could register your app as a service via a suitable service wrapper like Tanuki (it seems they have a free Community License option). Although this might be overkill. And it may be possible to get notification about the JVM shutting down when the system is closing (but I have no concrete experience with this).
http://www.pinvoke.net/default.aspx/powrprof.CallNtPowerInformation - Check out the link. It has almost all win32api for all windows function. You can call power management feature directly in your windows 7 laptop. For that create a Windows Service , that will use these specific api to notify the machine state.

Categories

Resources