SignalR Client application exit - c#

I have a problem with signalr.
I wrote a service that send a file from web server to a desktop app for later work.
The problem is when I need to close the app, eve I call connection.stop, connection.dispose, hub.dispose the app will not close and I have to kill via task manager.
Can someone help me?
Edit:
Here is the connection initialization
this.Connection = new Microsoft.AspNet.SignalR.Client.HubConnection(SisIdsEndPoint)
{
DeadlockErrorTimeout = new TimeSpan(deadlockDays, deadlockHours, deadlockMinutes)
};
_hub = Connection.CreateHubProxy("SisIdsRemoteClientHub");
this.Connection.Error += ConnectionOnError;
_hub.On<string, string, string, string, string, int>("GetData", GetData);
_hub.On<string, string>("Error", AddLog);
_hub.On("ConnectionOk", x => ConnectionOk(x));
_hub.On("DisconnectOk", x => DisconnectOk(x));
Connection.StateChanged += new Action<StateChange>(ConnChange);
Connection.Closed += new Action(ConClosed);
Connection.Start().Wait();
_hub.Invoke("Hello", SisIdsApiKey, this.Utenti).Wait();
I have removed the log lines After that there is the "GetData" method wich is a simple function that accept some parameter and save the file And when I close the app I call
Connection.Stop();
Connection.Dispose();
Connection = null;
After that I tried Application.Restart() but the window freeze and debuggind the code it will freeze on Connection.Stop()

Related

Getting location while app is terminated in Xamarin?

I have been working on a location-oriented project that I need to be able to track a user's location while the app is terminated.
I have a background service in my Android project and the Geolocator Plugin.
Just for reference, here are my Geolocator settings:
App.xaml.cs
public static async void StartListening()
{
if (CrossGeolocator.Current.IsListening)
return;
CrossGeolocator.Current.DesiredAccuracy = 10;
await CrossGeolocator.Current.StartListeningAsync(TimeSpan.FromSeconds(LOCATION_PING_SECONDS), 1, true, new Plugin.Geolocator.Abstractions.ListenerSettings
{
AllowBackgroundUpdates = true,
PauseLocationUpdatesAutomatically = false
});
CrossGeolocator.Current.PositionChanged += PositionChanged;
CrossGeolocator.Current.PositionError += PositionError;
}
This + my location service for Android work like a charm while the app is running and backgrounded, but obviously everything stops when the app is terminated.
Android/MainActivity.cs
public void StartLocationService()
{
powerManager = (PowerManager) GetSystemService(PowerService);
wakeLock = powerManager.NewWakeLock(WakeLockFlags.Full, "LocationHelper");
// create a new service connection so we can get a binder to the service
locationServiceConnection = new LocationServiceConnection(null);
// this event will fire when the Service connectin in the OnServiceConnected call
locationServiceConnection.ServiceConnected += (object sender, ServiceConnectedEventArgs e) => {
Console.WriteLine("Service Connected");
};
// Starting a service like this is blocking, so we want to do it on a background thread
new Task(() => {
// Start our main service
Console.WriteLine("App", "Calling StartService");
Android.App.Application.Context.StartService(new Intent(Android.App.Application.Context, typeof(LocationService)));
// bind our service (Android goes and finds the running service by type, and puts a reference
// on the binder to that service)
// The Intent tells the OS where to find our Service (the Context) and the Type of Service
// we're looking for (LocationService)
Intent locationServiceIntent = new Intent(Android.App.Application.Context, typeof(LocationService));
Console.WriteLine("App", "Calling service binding");
// Finally, we can bind to the Service using our Intent and the ServiceConnection we
// created in a previous step.
Android.App.Application.Context.BindService(locationServiceIntent, locationServiceConnection, Bind.AutoCreate);
}).Start();
Console.WriteLine("Aquiring Wake Lock");
wakeLock.Acquire();
}
Does anyone know of any tutorials for getting location updates even when the app is terminated? Is this even possible?
Thanks!
Also, I found this Xamarin forum post... The last post says he is able to get updates while the app is terminated from a service, but I have not been able to get the same outcome.

Embedded Nancy not listening

I read a couple of related questions which had an issue with accessing nency from a remote computer. However, I am unable to access nancy from my own pc.
Here is my code:
class Program
{
static void Main(string[] args)
{
HostConfiguration hostConfigs = new HostConfiguration();
//hostConfigs.RewriteLocalhost = true;
hostConfigs.UrlReservations.CreateAutomatically = true;
using (var host = new NancyHost(hostConfigs, new Uri("http://localhost:1234")))
{
host.Start();
Console.WriteLine("Running on http://+:1234");
Console.WriteLine(host.ToString());
}
Console.ReadKey();
}
}
public class HelloModule : NancyModule
{
public HelloModule()
{
Get["/"] = parameters => Response.AsJson("Success");
Get["/nancy"] = parameters => Response.AsJson("Success");
}
}
}
I am administrator on my PC and I do not get any exception. If I type http://localhost:1234 or http://127.0.0.1:1234 to my browser (with /nancy and without) I would expect a response. However, I do net get any reponse. Further, in the list produced with netstat -ano I do not see any process listing on port 1234. I downloaded the latest version of nancy via nuget.
Do you have any idea?
The following line should work as expected:
var host = new NancyHost(hostConfigs, new Uri("http://localhost:1234"))
But what happens with a using statement, is that anything specified between ( and ) (simply put) is disposed after the closing brace (}) of the same using statement. So what is actually happening is, the host gets created, is started, and is disposed right after it printed some lines to the console.
Simply put, move the ReadKey call inside the using statement. There it will wait until a key is pressed, and the host will be disposed after that event has occurred.

C# Windows 10 Bluetooth LE can't connect to server

I'm developing a c# desktop api with forms where I want to receive ACC data from a BLE server und display them in a chart.
So I'm running in a connection problem and I can't find any solution.
I can find my LE server Device with the watcher.
DevicePairingResult dpr = await device.DeviceInformation.Pairing.PairAsync(DevicePairingProtectionLevel.Encryption);
returns me "AlreadyPaired"
But when I do
device = await BluetoothLEDevice.FromBluetoothAddressAsync(bluetoothAddress: eventArgs.BluetoothAddress);
mGattService = device.GetGattService(MotionService_GUID);
mCharacteristic = mGattService.GetCharacteristics(ACC_Characteristic_GUID)[0];
and then
var con = device.ConnectionStatus;
I receive "Disconnected" in con.
I am bound with de device on windows( I searched for it in Windows and entered the Code) but I am not connected(based on the Status in the windows info center).
I've read in another Thread in the windows c# developer page that it should not be necessary anymore to pair the device manually.
I'm pretty shure that the rest of my code works because sometimes I can get a connection( pretty confusing for me) and see the right Data in my chart.
Right now I just want to reach a stable connection before changing other part of my code.
Anyone any idea how to solve this?
Thx medTech
Edit:
Here is part of the Code:
Scanning for BLE
private void button1_Click(object sender, EventArgs e)
{
// Create Bluetooth Listener
var watcher = new BluetoothLEAdvertisementWatcher();
watcher.ScanningMode = BluetoothLEScanningMode.Active;
// Register callback for when we see an advertisements
watcher.Received += OnAdvertisementReceivedAsync;
// Wait 5 seconds to make sure the device is really out of range
watcher.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMilliseconds(5000);
watcher.SignalStrengthFilter.SamplingInterval = TimeSpan.FromMilliseconds(2000);
// Starting watching for advertisements
watcher.Start();
}
Connect to Server:
private async void OnAdvertisementReceivedAsync(BluetoothLEAdvertisementWatcher watcher, BluetoothLEAdvertisementReceivedEventArgs eventArgs)
{
// Filter for specific Device
if (eventArgs.Advertisement.LocalName == "MYDEVICE")
{
watcher.Stop();
var MotionService_GUID = new Guid("00002000-0000-1000-8000-00805F9B34FB");
var ACC_Characteristic_GUID = new Guid("00002001-0000-1000-8000-00805F9B34FB");
device = await BluetoothLEDevice.FromBluetoothAddressAsync(bluetoothAddress: eventArgs.BluetoothAddress);
DevicePairingResult dpr = await device.DeviceInformation.Pairing.PairAsync(DevicePairingProtectionLevel.Encryption);
mGattService = device.GetGattService(MotionService_GUID);
mCharacteristic = mGattService.GetCharacteristics(ACC_Characteristic_GUID)[0];
GattDeviceServicesResult result = await device.GetGattServicesAsync();
GattCommunicationStatus status1 = await ReadFromCharacteristicAsync(mCharacteristic);
var con = device.ConnectionStatus;
while (status1 == GattCommunicationStatus.Success)
{
try
{
status1 = await ReadFromCharacteristicAsync(mCharacteristic);
}
catch
{
Console.WriteLine("ERROR");
status1 = GattCommunicationStatus.Unreachable;
}
}
}
}
Read from Characteristic:
async Task ReadFromCharacteristicAsync(GattCharacteristic mCharacteristic)
{
GattReadResult readResult = await mCharacteristic.ReadValueAsync(BluetoothCacheMode.Uncached);
if (readResult.Status == GattCommunicationStatus.Success)
{
byte[] data = new byte[readResult.Value.Length];
DataReader.FromBuffer(readResult.Value).ReadBytes(data);
if (chart1.IsHandleCreated)
{
this.Invoke((MethodInvoker)delegate { updateChart(data); });
}
return readResult.Status;
}
return readResult.Status;
}
Terminate Connection
private async Task<bool> ClearBluetoothLEDeviceAsync()
{
mCharacteristic.Service.Dispose();
mGattService.Dispose();
await device.DeviceInformation.Pairing.UnpairAsync();
device?.Dispose();
device = null;
GC.Collect();
return true;
}
SO now when I connect the first time to the Server, I only receive zeros which shows me that the there might be a authentication Error.
After that I always receive this Error:
"System.ArgumentException" in mscorlib.dll with a notification that there is noch executable Code left because all Threads are doing some asynchronous stuff.
This Error gets thrown when I try to read from the Characteristic.
I never coded in c# before so I am not shure if there is an error in my asynchronous part oder the communication part.
Thanks you
Pairing is not the same as connecting!
I really advise using the BLE-advertisementWatcher to select and connect to your device.
The reason is that many BLE-devices don't save their pairing status.
In windows device-watcher once paired, the device stays paired even if it is switched off or out of reach.
Also many times the connection status is kept, unless the device is unpaired and disposed in code or removed in windows settings.
All BLE-devices that I know of start advertising as soon as there is no connection for some time.
This time depends on the device, but most of the time within seconds.
So don't pair but just connect if the device is advertising.

SignalR Client Trigger Events

I'm trying to replicate behavior like a client browser but in C# (Performance reason). What I'm trying to set out to achieve is that for every new events received, my program should trigger the server side (Hub) which would then notify the client. Rather than having a while loop which would repeatedly hit the hub method every time even if theres no messages, is there a way to treat it as a trigger/detection so that once message is detected then execute Hub method ? Hope this makes sense
Snapshot of Client code below:
IHubProxy _hub;
string url = #"http://localhost:8080/";
var connection = new HubConnection(url);
_hub = connection.CreateHubProxy("PersonHub");
connection.Start().Wait();
//client side method
_hub.On("checkedIn", x => Console.WriteLine(x));
Console.WriteLine("Enter Person Name");
var answer = Console.ReadLine();
while (true) // Better way doing this? trigger or detect new message?
{
//server side method
_hub.Invoke("GetByName", answer).Wait();
}
Snapshot of Hub code below:
[HubName("PersonHub")]
public class PersonHub: Hub
{
public Person GetByName(string name)
{
//logic and etc ...
Clients.All.checkedIn(name);
}
}
By setting the while loop to true this means this will always call the server side method (Hub method) which I dont want to. If theres new events triggered then it should hit the hub method. Is there a way to somehow listen for new message but not to execute if no messages has been detected?
A possible solution is:
string line;
while ((line = Console.ReadLine()) != "exit")
{
_hub.Invoke("GetByName", line).Wait();
}

Detecting a web socket connection drop

In my Windows 8 JS application, I have a web socket object defined like this:
var webSocket = new Windows.Networking.Sockets.MessageWebSocket();
webSocket.control.messageType = Windows.Networking.Sockets.SocketMessageType.utf8;
webSocket.onmessagereceived = that._onMessageReceived;
webSocket.onclosed = that._onClosed;
I connect using webSocket.connectAsync(uri).done(/* ... */) and that part works fine.
If I stop my web server on the other end, my application doesn't get notified and thinks the connection is still alive. The 'closed' event never fires, and there doesn't seem to be any 'Error' event.
Is there a way to monitor the connection status?
Figured it out. The messagereceived event actually fires when the connection fails. Inside the handler, you can use a try catch block around the data reader operation.
try {
var dataReader = args.getDataReader();
var msg = dataReader.readString(dataReader.unconsumedBufferLength);
} catch (ex) {
var error = Windows.Networking.Sockets.SocketError.getStatus(ex.number);
// do something
}
Is this a specific Windows 8 question? I've tested the following to work on Windows 7, OSX and Ubuntu (using reasonably new versions of Firefox, Safari and Chrome):
var s = new WebSocket("ws://"+window.location.hostname+":9876");
s.onopen = function(e) {
console.log("opened socket for unidrive log");
}
s.onclose = function(e) {
console.log("closed");
}
s.onmessage = function(e) {
console.log("got message: " + e.data);
}
The onclose event fires immediately if the web-server isn't running to start with, or fires on killing the server.
Thank you for this Information - really weird why the socket don't raise the closed-event, but it works great.
One more info for C# developers: to determine the correct exception-errorstatus you have to do call the WebSocketError.GetStatus(hresult) instead of the SocketError.GetStatus(hresult) method.
try
{
using (DataReader reader = e.GetDataReader())
{
reader.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8;
string rawMessage = reader.ReadString(reader.UnconsumedBufferLength);
// Do something with the message...
}
}
catch (Exception ex)
{
var errorStatus = Windows.Networking.Sockets.WebSocketError.GetStatus(ex.HResult);
if (errorStatus == WebErrorStatus.ConnectionAborted)
{
// Handle the connection-abort...
}
}

Categories