I'm trying to implement trial version for my xamarin.forms application. What is the best way to achieve it?
I had an idea to store a unique ID inside the application with help of Xamarin.Essentials.SecureStorage or inside Xamarin.Essentials.Preferences and compare it with data inside my database at the server, but problem is that all the data getting deleted after each reinstallation of application.
Also, I had an idea to access Xamarin.Essentials.DeviceInfo.Name and verify device name during each application launch, but I'm not sure does this property returns the unique device name during each attempt or not.
I'm new to Xamarin.Forms so I'll appreciate any help. Thanks in advance.
//using Xamarin.Essentials.Preferences
var id = Preferences.Get("my_id", string.Empty);
if (string.IsNullOrWhiteSpace(id))
{
id = System.Guid.NewGuid().ToString();
Preferences.Set("my_id", id);
}
// using Xamarin.Essentials.SecureStorage
private async void Save()
{
try
{
await SecureStorage.SetAsync("bla", "secret-oauth-token-
value");
}
catch (Exception ex)
{
// Possible that device doesn't support secure storage on
device.
}
}
private async Task<string> Get()
{
try
{
return await SecureStorage.GetAsync("bla");
}
catch (Exception ex)
{
// Possible that device doesn't support secure storage on
device.
}
return null;
}
Is there some sort of login? Then you can always just store a key on the server that determines if it is paid. And save on the device for offline use. That way you will know if its a paid version. Otherwise publish a lite version seperate on the store
Related
I would like to pick up a specific document from _changes in couchDB.
Here is my query line, where FEED should be "continuous" and HEARTBEAT = "5000"
"?filter=_doc_ids&feed="+FEED+ "&include_docs=true&heartbeat="+HEARTBEAT;
I dont want to request the DB all the time to get the document, but for the DB to push the changes using the above parameters.
This means my c# code needs to keep a connection open for CouchDB to push the changes. This is being executed in its own thread.
I can get data using feed=longpoll, but the c# code just hangs when using continuous.
I'm thinking it has something to do with that im looking at it as an async to produce a .Result, but it should be a stream, so ive tried to do it using streams, but that just turned into a clusterf***. I spent too much time, and could not get it to work. It just stopped executing but not breaking with an exception, so i could not bughunt it.
Therefor i returned to this method, hoping it is possible with a little help :) It works for longpoll, but not for continuous.
internal void Listen (ref JobList jobList)
{
HttpResponseMessage result = null;
try
{
while (true)
{
result = _httpClient.SendAsync(_requestMessage).Result;
var stringResult = result.Content.ReadAsStringAsync();
var resultObject = JsonConvert.DeserializeObject<ImportJobsResponse>(stringResult.Result);
// Transfer the read objects to the jobList
if (null != resultObject)
{
foreach (ImportJob job in resultObject.results[0].doc.ImportJobs)
{
jobList.addJob(job);
}
}
}
} catch (JsonSerializationException jex)
{
// handle error, and write to log.
} catch (Exception ex) // Needs to find out what errors can come here when using httpclient
{
// handle error, and write log.
}
}
Can anybody help :) ty in advance.
I have to remove the pairing(Bonding) information from the Device, but after executing that and go back to Bluetooth settings and check the paired devices it is still showing as paired. It is not clearing the information.
The address we provided is:F8:F6:35:D6:35:64
Thank's in advance for the solution.
This has to be handled in platform specific code.
On iOS it is not possible. Only manually "forgetting" in the settings. See here
For the Android Part see here.
For android,get the Bluetooth list paired by the phone in one way and then cancel the Bluetooth pairing through the reflection mechanism.
BluetoothAdapter bluetoothAdapter;
IEnumerable<BluetoothDevice> bondeddevices;
private void removepairdevice()
{
bluetoothAdapter = BluetoothAdapter.DefaultAdapter;
bondeddevices = bluetoothAdapter.BondedDevices;
foreach(BluetoothDevice device in bondeddevices)
{
unpairdevice(device);
}
}
private void unpairdevice(BluetoothDevice device)
{
try
{
Method m = device.Class.GetMethod("removeBond",null);
m.Invoke(device,null);
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
}
I want to get an alert when a service (grafana or influxdb) in an Azure virtual machine (Ubuntu 16.04) has stopped. I'd like to use c# to connect to the VM and check the status of grafana and influxdb services. Can anyone share a code sample that implements this?
Both services provide health endpoints that can be used to check their status from a remote server. There's no need to open a remote shell connection. In fact, it would be impossible to monitor large server farms if one had to SSH to each one.
In the simplest case, and ignoring networking issues, one can simply hit the health endpoints to check the status of both services. A rough implementation could look like this :
public async Task<bool> CheckBoth()
{
var client = new HttpClient
{
Timeout = TimeSpan.FromSeconds(30)
};
const string grafanaHealthUrl = "https://myGrafanaURL/api/health";
const string influxPingUrl = "https://myInfluxURL/ping";
var (grafanaOK, grafanaError) = await CheckAsync(client, grafanaHealthUrl,
HttpStatusCode.OK, "Grafana error");
var (influxOK, influxError) = await CheckAsync(client, influxPingUrl,
HttpStatusCode.NoContent,"InfluxDB error");
if (!influxOK || !grafanaOK)
{
//Do something with the errors
return false;
}
return true;
}
public async Task<(bool ok, string result)> CheckAsync(HttpClient client,
string healthUrl,
HttpStatusCode expected,
string errorMessage)
{
try
{
var status = await client.GetAsync(healthUrl);
if (status.StatusCode != expected)
{
//Failure message, get it and log it
var statusBody = await status.Content.ReadAsStringAsync();
//Possibly log it ....
return (ok: false, result: $"{errorMessage}: {statusBody}");
}
}
catch (TaskCanceledException)
{
return (ok: false, result: $"{errorMessage}: Timeout");
}
return (ok: true, "");
}
Perhaps a better solution would be to use Azure Monitor to ping the health URLs periodically and send an alert if they are down.
Here is something you can use to connect to Azure linux using SSH in c#
using (var client = new SshClient("my-vm.cloudapp.net", 22, "username", "password​"))
{
client.Connect();
Console.WriteLine("it worked!");
client.Disconnect();
Console.ReadLine();
}
Usually SSH server only allow public key auth or other two factor auth.
Change your /etc/ssh/sshd_configuncomment #PasswordAuthentication yes
# Change to no to disable tunnelled clear text passwords
#PasswordAuthentication yes
Later you can poll for installed services.
Also for an alternative solution, you can deploy a rest api in your linux VM to check the status of your service and the call it from C# httpclient for the status.
Hope it helps
I have an MVC application and I'm registering a device to IOT using a foreach loop.
I want to show messages one by one when one device is done with registration. How can I show the messages on the view?
Code in the controller method -
foreach (var deviceId in collection)
{
try
{
// save device information into database
Models.Device newDevice = new Models.Device()
{
Id = Guid.NewGuid(),
Device = deviceId
};
_deviceRepository.InsertDevice(newDevice);
_deviceRepository.Save();
}
catch (DeviceAlreadyExistsException)
{
device = await registryManager.GetDeviceAsync(deviceId);
ViewBag.Message = "device already present";
}
}
}
catch (Exception ex)
{
ViewBag.Message = "Error";
throw ex;
}
ViewBag.Message = "device register successfully - " + deviceId;
return View("Index")
How can I show ViewBag.Message one by one on view or partial view ?
If an error occurs it will display an error message.
If success then one by one like notification we have to show messagesuccess message.
For example I have 10 items then the foreach will run 10 times, after every device success we need to show a message on the UI:
device register successfully device1
device register successfully device2 and so on ...
I know ViewBag won't be useful, what approach can I take?
I think you would need to take a different approach for this behaviour.
Look into using signalR so you can communicate with the client side view whilst a server side operation is taking place.
You could use this to show a progression loading bar, or give feedback ever time a device has registered.
using IPC over local TCP to communicate from Client to a Server thread. The connection itself doesn't seem to be throwing any errors, but every time I try to make one of the associated calls, I get this message:
System.Runtime.Remoting.RemotingException: Could not connect to an IPC Port: The System cannot Find the file specified
What I am attempting to figure out is WHY. Because this WAS working correctly, until I transitioned the projects in question (yes, both) from .NET 3.5 to .NET 4.0.
Listen Code
private void ThreadListen()
{
_listenerThread = new Thread(Listen) {Name = "Listener Thread", Priority = ThreadPriority.AboveNormal};
_listenerThread.Start();
}
private void Listen()
{
_listener = new Listener(this);
LifetimeServices.LeaseTime = TimeSpan.FromDays(365);
IDictionary props = new Hashtable();
props["port"] = 63726;
props["name"] = "AGENT";
TcpChannel channel = new TcpChannel(props, null, null);
ChannelServices.RegisterChannel(channel, false);
RemotingServices.Marshal(_listener, "Agent");
Logger.WriteLog(new LogMessage(MethodBase.GetCurrentMethod().Name, "Now Listening for commands..."));
LogEvent("Now Listening for commands...");
}
Selected Client Code
private void InitializeAgent()
{
try
{
_agentController =
(IAgent)RemotingServices.Connect(typeof(IAgent), IPC_URL);
//Note: IPC_URL was originally "ipc://AGENT/AGENT"
// It has been changed to read "tcp://localhost:63726/Agent"
SetAgentPid();
}
catch (Exception ex)
{
HandleError("Unable to initialize the connected agent.", 3850244, ex);
}
}
//This is the method that throws the error
public override void LoadTimer()
{
// first check to see if we have already set the agent process id and set it if not
if (_agentPid < 0)
{
SetAgentPid();
}
try
{
TryStart();
var tries = 0;
while (tries < RUNCHECK_TRYCOUNT)
{
try
{
_agentController.ReloadSettings();//<---Error occurs here
return;
} catch (RemotingException)
{
Thread.Sleep(2000);
tries++;
if (tries == RUNCHECK_TRYCOUNT)
throw;
}
}
}
catch (Exception ex)
{
HandleError("Unable to reload the timer for the connected agent.", 3850243, ex);
}
}
If you need to see something I haven't shown, please ask, I'm pretty much flying blind here.
Edit: I think the issue is the IPC_URL String. It is currently set to "ipc://AGENT/AGENT". The thing is, I have no idea where that came from, why it worked before, or what might be stopping it from working now.
Update
I was able to get the IPC Calls working correctly by changing the IPC_URL String, but I still lack understanding of why what I did worked. Or rather, why the original code stopped working and I needed to change it in the first place.
The string I am using now is "tcp://localhost:63726/Agent"
Can anyone tell me, not why the new string works, I know that...but Why did the original string work before and why did updating the project target to .NET 4.0 break it?