C# BLE DeviceConnectionChanged event fires multiple times until shutoff device - c#

I connected to a device and read data successfully. Then I shutoff device, DeviceConnectionChanged event fire with Disconnected connection status, then turn on device, DeviceConnectionChanged event fire with Connected connection status, after that loop Connected then Disconnected, ... until shutoff device.
This is connect function:
public async Task<ConnectionResult> ConnectAsync(string deviceId, Guid serviceUUID)
{
_device = await BluetoothLEDevice.FromIdAsync(deviceId);
if (_device == null)
{
return new Schema.ConnectionResult()
{
IsConnected = false,
ErrorMessage = "Could not find specified device"
};
}
if (!_device.DeviceInformation.Pairing.IsPaired)
{
_device = null;
return new Schema.ConnectionResult()
{
IsConnected = false,
ErrorMessage = "Device is not paired"
};
}
_device.ConnectionStatusChanged -= DeviceConnectionStatusChanged;
_device.ConnectionStatusChanged += DeviceConnectionStatusChanged; // <===== event here
...
}
private void DeviceConnectionStatusChanged(BluetoothLEDevice sender, object args)
{
OnConnectionStatusChanged(new ConnectionStatusChangedEventArgs()
{
IsConnected = sender != null && (sender.ConnectionStatus == BluetoothConnectionStatus.Connected)
}); // <==== always fire after reconnect
}
public event EventHandler<Events.ConnectionStatusChangedEventArgs> ConnectionStatusChanged;
protected virtual void OnConnectionStatusChanged(Events.ConnectionStatusChangedEventArgs e)
{
ConnectionStatusChanged?.Invoke(this, e);
}
I want to auto reconnect and read data when device available. How can I do that?

Related

How to send information from a class using a backgroundworker, back to the mainform

Hi,
I'm trying to write a UDP-client that listens to a port, and then display the incoming data in a textbox.
I have written a class; UDP_Receive() that starts a backgroundworker that listens to a specified port and receives the data. The code is based on this question; C# .Net receiving UDp packets in separater thread and application exit
I think I have solved the issues with the blocking .receive() by following the accepted answer in this question; How can I safely terminate UdpClient.receive() in case of timeout?
My question is how do I get the data I receive in the backgroundworkerthread (that I created in my class) back to the mainthread, so that I can display it in a textbox?
I thought of using Invoke, but I don't have any references to the textbox in my class.
textBox_UdpPositionInData.Invoke(new EventHandler(delegate
{
textBox_UdpPositionInData.Text = receivedData;
}));
I found a very similar question about a tcp-server, but I can't see how to apply that solution here Send data from a background thread to the main thread
Any thoughts or suggestions are of course much appreciated!
Many Thanks!
internal class UDP_Receive
{
private int _portToListen = 2003;
private volatile bool listening;
BackgroundWorker _backgroundWorker;
//Constructor
public UDP_Receive()
{
Debug.WriteLine("Constructor: UDP_Receive");
this.listening = false;
}
public void StartListener()
{
if ( (_backgroundWorker==null) || (!_backgroundWorker.IsBusy))
{
_backgroundWorker = new BackgroundWorker();
_backgroundWorker.DoWork += listenForUDPPackages_DoWork;
_backgroundWorker.RunWorkerCompleted +=listenForUDPPackages_RunWorkerCompleted;
_backgroundWorker.WorkerSupportsCancellation = true;
_backgroundWorker.RunWorkerAsync();
Debug.WriteLine("Creates a new thread: " + _backgroundWorker.ToString() );
// We are listening
this.listening = true;
}
}
public void StopListener()
{
// The user cancelled the UDP Port listening
this.listening = false;
// Cancel the backgroundworker
_backgroundWorker.CancelAsync();
// Debug
Debug.WriteLine("Stops current thread: " + _backgroundWorker.ToString());
}
public bool IsListening
{
get { return this.listening; }
}
public int PortToListen
{
get { return this._portToListen; }
set { this._portToListen = value; }
}
private void listenForUDPPackages_DoWork(object sender, DoWorkEventArgs ev)
{
UdpClient? listener = null;
try
{
listener = new UdpClient(_portToListen);
}
catch (SocketException)
{
//do nothing
}
if (listener != null)
{
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, _portToListen);
try
{
while (this.listening)
{
Debug.WriteLine("Waiting for UDP broadcast to port " + _portToListen);
byte[] receivedBytes = new byte[1024];
string receivedData;
bool timeTracker = TrackFunction(TimeSpan.FromSeconds(2), () =>
{
receivedBytes = listener.Receive(ref groupEP);
});
Debug.WriteLine("Timetracker result: " + timeTracker.ToString());
if (receivedBytes == null || receivedBytes.Length == 0)
{
// We did not recieve any data
Debug.WriteLine("No data received befor Time out ");
}
else
{
// We managed to receive some data!
// No we want to process the data and then send the result to the Thread that initiated the class.
receivedData = Encoding.Default.GetString(receivedBytes);
Debug.WriteLine("Data received: " + receivedData);
}
}
catch (Exception e)
{
Debug.WriteLine("Exception: " + e.ToString());
}
finally
{
listener.Close();
Debug.WriteLine("Finally: Done listening for UDP broadcast");
}
}
else
{
Debug.WriteLine("Error: UdpClient(_portToListen) returned null");
}
}
private void listenForUDPPackages_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e == null || e.Result == null)
{
Debug.WriteLine("listenForUDPPackages_RunWorkerCompleted e = null");
}
else
{
if (e.Cancelled)
{
Debug.WriteLine("Operation was canceled");
}
else if (e.Error != null)
{
Debug.WriteLine("Error: " + e.Error.Message);
}
else
{
Debug.WriteLine("Result: " + e.Result.ToString());
}
}
}
private static bool TrackFunction(TimeSpan timeSpan, Action codeBlock)
{
try
{
Task task = Task.Factory.StartNew(() => codeBlock());
task.Wait(timeSpan);
return task.IsCompleted;
}
catch (AggregateException ae)
{
throw ae.InnerExceptions[0];
}
}
}
You can write this kind of code to keep the UI separate from the UDP_Receive class:
internal class UDP_Receive
{
private Action<string> _invoke;
public UDP_Receive(Action<string> invoke)
{
_invoke = invoke;
}
public void Foo()
{
_invoke("Hello");
}
}
When you declare the class you then do it like this:
var ur = new UDP_Receive(t => textBox.Invoke(() => textBox.Text = t));
Now it's just a matter of calling ur.Foo() (in my example) to update the UI.

Trouble establishing WebSocket4Net connection with Xamarin.Forms Android project

We've recently reorganized our socket connections to have them use more shared code. I currently have the iOS project able to connect to the web socket and respond to events but I haven't been successful yet with the android project. It will try to connect and eventually hit the disconnect event with data stating "transport error". I'm wondering if anyone with more experience with sockets knows if there are any key differences between an iOS connection and an android connection? I'll post some of my code below and try to cut out the chunks I don't think are related. Thank you!!
This is my shared class
public bool InitAndConnect()
{
//Create a socket
sock = DependencyService.Get<IDabSocket>(DependencyFetchTarget.NewInstance);
//Get the URL to use
ContentConfig config = ContentConfig.Instance;
string uri;
if (GlobalResources.TestMode)
{
uri = config.app_settings.stage_journal_link;
}
else
{
uri = config.app_settings.prod_journal_link;
}
//Create list of events to monitor (basic connection events are already monitored)
List<String> events = new List<String>();
events.Add("room_error");
events.Add("join_error");
events.Add("auth_error");
events.Add("update");
//Register for notifications from the socket
sock.DabSocketEvent += Sock_DabSocketEvent;
//Init the socket
sock.Init(uri, events);
//Connect the socket
sock.Connect();
return true;
}
public bool JoinRoom(DateTime date)
{
//Joins a room for a specific date
var room = date.ToString("yyyy-MM-dd");
var token = AuthenticationAPI.CurrentToken;
var data = new DabJournalObject(room, token);
var json = JObject.FromObject(data);
//Send data to the socket
sock.Emit("join", json);
//Store the date we're using
currentDate = date;
return true;
}
//IsConnected returns a bool indicating whether the socket is currently connected.
//This is a bindable property
public bool IsConnected
{
get
{
return sock == null ? false : sock.IsConnected;
}
}
//Opposite of IsConnected used for binding reasons.
public bool IsDisconnected
{
get
{
return sock == null ? true : !sock.IsConnected;
}
}
private void Sock_DabSocketEvent(object sender, DabSocketEventHandler e)
{
//An event has been fired by the socket. Respond accordingly
//Log the event to the debugger
Debug.WriteLine($"{e.eventName} was fired with {e.data}");
//Take action on the event
switch (e.eventName.ToLower())
{
case "disconnected": //Socket disconnected
Sock_Disconnected(e.data);
break;
case "connected": //Socket connected
Sock_Connected(e.data);
break;
case "reconnecting": //Socket reconnecting
sock.Connect();
//do nothing for now
break;
case "reconnected": //Socket reconnected
Sock_Connected(e.data);
break;
case "room_error": //Error with a room
Sock_ErrorOccured(e.eventName, e.data);
break;
case "join_error": //Error joining
Sock_ErrorOccured(e.eventName, e.data);
break;
case "auth_error": //Error with authentication
Sock_ErrorOccured(e.eventName, e.data);
break;
case "update": //update happened externally
Sock_ExternalUpdateOccured(e.eventName, e.data);
break;
default:
break;
}
}
private void Sock_Disconnected(string data)
{
//The socket got disconnected.
//Notify UI
OnPropertyChanged("IsConnected");
OnPropertyChanged("IsDisconnected");
}
private void Sock_Connected(object data)
{
//The socket has connected or reconnected. Take appropriate action
//Notify UI
OnPropertyChanged("IsConnected");
OnPropertyChanged("IsDisconnected");
}
/* Events to handle Binding */
public virtual void OnPropertyChanged(string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
this is my android class
public bool IsConnected
{
get
{
return isConnected;
}
}
public void Connect(string token)
{
//Make sure the socket is initialized
if (!isInitialized) throw new Exception("You must initialize the socket before using it");
sock.Connect();
}
public void Init(string Uri, List<String> events)
{
//Initialize the socket
try
{
sock = IO.Socket(Uri);
isInitialized = true;
//Set up standard events
sock.On("connect", data => OnConnect(data));
sock.On("disconnect", data => OnDisconnect(data));
sock.On("reconnect", data => OnReconnect(data));
sock.On("reconnecting", data => OnReconnecting(data));
//Set up custom events requested by the caller
foreach (string s in events)
{
sock.On(s, data => OnEvent(s, data));
}
}
catch (Exception ex)
{
isInitialized = false;
isConnected = false;
}
}
private object OnEvent(string s, object data)
{
//A requested event has fired - notify the calling app so it can handle it.
//Notify the listener
DabSocketEvent?.Invoke(this, new DabSocketEventHandler(s, data.ToString()));
return data;
}
private object OnConnect(object data)
{
//Socket has connected (1st time)
isConnected = true;
//Notify the listener
DabSocketEvent?.Invoke(this, new DabSocketEventHandler("connected", data.ToString()));
//Return
return data;
}
private object OnDisconnect(object data)
{
//Socket has disconnected
isConnected = false;
//Notify the listener
DabSocketEvent?.Invoke(this, new DabSocketEventHandler("disconnected", data.ToString()));
//Return
return data;
}
public void Disconnect()
{
if (IsConnected)
{
sock.Disconnect();
}
}
public void Connect()
{
sock.Connect();
}
public void Emit(string Command, object Data)
{
sock.Emit(Command, Data);
}
public void Open()
{
sock.Open();
}
My iOS class looks really similar to the droid class.. besides the Open().. Not sure what is hanging up on the android side.
My SocketIoClientDotNet nuget package versions didn't match between my iOS and android projects. Once I updated my android package to match the version in the iOS project everything worked great.

Xamarin IOS: BLE

I am trying to connect to my Bluetooth Low Energy Device. After finding the device and getting the peripheral object. I cannot connect to the Bluetooth Device from my iPhone and it does not call central.ConnectedPeripheral method.
Another issue is that i cannot register the event central.ConnectedPeripheral += ConnectedPeripheral in the method.
Error: System.InvalidOperationException: Event registration is overwriting existing delegate. Either just use events or your own delegate:
class IOSBluetooth : IBluetooth
{
private readonly CBCentralManager central;
private CBPeripheral activePeripheral;
SimpleCBCentralManagerDelegate myCentralDelegate;
public bool IsScanning { get; private set; }
List<CBPeripheral> connectedDevices = new List<CBPeripheral>();
//List<CBPeripheral> discoveredDevices = new List<CBPeripheral>();
/// <summary>
/// Gets the current Bluetooth instance
/// </summary>
/// <value>The Bluetooth Adapter instance</value>
public IOSBluetooth(SimpleCBCentralManagerDelegate myCenDel)
{
myCentralDelegate = myCenDel;
central = new CBCentralManager(myCentralDelegate, DispatchQueue.CurrentQueue);
InitializeEvents();
// central.DiscoveredPeripheral += DiscoveredPeripheral; // Called when peripheral is discovered (Working)
// central.UpdatedState += UpdatedState; // Method Implemented - Tells us about the bluetooth powered state (On or Off). (Working)
// central.ConnectedPeripheral += ConnectedPeripheral; // Devices that are connected to Iphone -> Services and Characteristics discovery start from here
// central.DisconnectedPeripheral += DisconnectedPeripheral; // Disconnect the device from the iphone
// central.FailedToConnectPeripheral += FailedToConnectPeripheral; // Failed to connect to Bluetooth Device
}
void InitializeEvents()
{
try
{
// central.ConnectedPeripheral += ConnectedPeripheral;
central.FailedToConnectPeripheral += FailedToConnectPeripheral;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message, "Intialization Failes");
Console.WriteLine("Bluetooth.Connect " + ex.Message);
}
}
public void FailedToConnectPeripheral(object sender, CBPeripheralErrorEventArgs e)
{
Console.WriteLine("Failed to Connect to Peripheral");
}
private void DisconnectedPeripheral(object sender, CBPeripheralErrorEventArgs e)
{
// when a peripheral disconnects, remove it from our running list.
if (connectedDevices.Contains(e.Peripheral))
{
connectedDevices.Remove(e.Peripheral);
}
}
public void ConnectToPeripheral(CBPeripheral peripheral)
{
central.ConnectPeripheral(peripheral, new PeripheralConnectionOptions { NotifyOnConnection = true, NotifyOnDisconnection = true, NotifyOnNotification = true });
}
private void UpdatedState(object sender, EventArgs e)
{
throw new NotImplementedException();
}
//public override void DiscoveredPeripheral(object sender, CBDiscoveredPeripheralEventArgs e)
//{
// Console.WriteLine("DiscoveredPeripheral: {0}", e.Peripheral.Name);
// discoveredDevices.Add(e.Peripheral);
//}
public void ConnectedPeripheral(object sender, CBPeripheralEventArgs e)
{
if (!connectedDevices.Contains(e.Peripheral))
{
connectedDevices.Add(e.Peripheral);
}
activePeripheral = e.Peripheral;
Console.WriteLine("Connected to " + activePeripheral.Name);
if (activePeripheral.Delegate == null)
{
activePeripheral.Delegate = new SimplePeripheralDelegate();
//Begins asynchronous discovery of services
activePeripheral.DiscoverServices();
}
}
public async void BeginScanningForDevices()
{
Console.WriteLine("BluetoothLEManager: Starting a scan for devices.");
// start scanning
IsScanning = true;
central.ScanForPeripherals((CBUUID[])null); // Discover all the devices and Initiates async calls of DiscoveredPeripheral
// in 10 seconds, stop the scan
await Task.Delay(10000);
// if we're still scanning
if (IsScanning)
{
Console.WriteLine("BluetoothLEManager: Scan timeout has elapsed.");
StopScanningForDevices();
}
}
/// <summary>
/// Stops the Central Bluetooth Manager from scanning for more devices. Automatically
/// called after 10 seconds to prevent battery drain.
/// </summary>
public void StopScanningForDevices()
{
Console.WriteLine("BluetoothLEManager: Stopping the scan for devices.");
IsScanning = false;
central.StopScan();
}
public IEnumerable<string> ListDevices()
{
return myCentralDelegate.DiscoveredDevices.Keys;
}
public bool Connect(string DeviceName)
{
StopScanningForDevices();
if (!myCentralDelegate.DiscoveredDevices.ContainsKey(DeviceName))
return false;
var device = myCentralDelegate.DiscoveredDevices[DeviceName];
// central.ConnectPeripheral(device, new PeripheralConnectionOptions { NotifyOnConnection = true, NotifyOnDisconnection = true, NotifyOnNotification = true });
central.ConnectPeripheral(device);
return true;
}
public void StartScanning()
{
if(central.State == (CBCentralManagerState.PoweredOn))
BeginScanningForDevices();
}
public void StopScanning()
{
StopScanningForDevices();
}
}
To get rid of the "Error: System.InvalidOperationException: Event registration is overwriting existing delegate. Either just use events or your own delegate" error, implement the ConnectedPeripheral method in the SimpleCBCentralManagerDelegate class. That class is being used as the iOS delegate (not to be confused with a C# delegate) so all of the events from CBCentralManager central are being handled in the relevant methods in the SimpleCBCentralManagerDelegate class.
The idea here is that you can either use the iOS style delegate/protocol pattern, where a delegate class that implements an Obj-C/iOS protocol is assigned as the iOS/Obj-C delegate for the class that will call those protocol methods, or you can use C# style event subscriptions, but you can't use both on the same object.
More info on this is discussed on this document: https://learn.microsoft.com/en-us/xamarin/ios/app-fundamentals/delegates-protocols-and-events
It's a long read but well worth it if you are developing using Xamarin.iOS.

Sending information from windows phone 8 to Pc Window 7 windows forms

I am trying to send information from my windows phone to the computer. I read some where that the usb cable is treated like a Ethernet cable. I created a server and a client(Phone is client) to try to send information. The program sends a message every time it presses enter.
Client Side
public sealed partial class MainPage : Page
{
private bool Connected;
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
}
/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached.
/// This parameter is typically used to configure the page.</param>
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// TODO: Prepare page for display here.
// TODO: If your application contains multiple pages, ensure that you are
// handling the hardware Back button by registering for the
// Windows.Phone.UI.Input.HardwareButtons.BackPressed event.
// If you are using the NavigationHelper provided by some templates,
// this event is handled for you.
}
private DatagramSocket dataGramSocket = new DatagramSocket();
private DataWriter socketWriter;
private bool messageSent;
private static string port = "138";
private void Grid_Loaded(object sender, RoutedEventArgs e)
{
dataGramSocket.MessageReceived += dataGramSocket_MessageReceived;
StartListener();
}
void dataGramSocket_MessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
{
}
private async void StartListener()
{
string IpHostname = "127.0.0.1";
var IpAdresses = NetworkInformation.GetHostNames();
for (int i = 0; i < IpAdresses.Count; i++)
{
if (IpAdresses[i].IPInformation != null)
{
if (IpAdresses[i].IPInformation.NetworkAdapter.IanaInterfaceType == 6 && IpAdresses[i].DisplayName != null)
{
IpHostname = IpAdresses[i].DisplayName;
break;
}
else if (IpAdresses[i].IPInformation.NetworkAdapter.IanaInterfaceType == 71 && IpAdresses[i].DisplayName != null)
{
IpHostname = IpAdresses[i].DisplayName;
break;
}
}
}
HostName host = new HostName(IpHostname);
//EndpointPair endpoint = new EndpointPair(localHostName,)
await dataGramSocket.BindServiceNameAsync(port);
await dataGramSocket.ConnectAsync(host, port);
socketWriter = new DataWriter(dataGramSocket.OutputStream);
Connected = true;
}
private async void SendPacket()
{
await socketWriter.StoreAsync();
messageSent = true;
}
private void TextBox1_KeyDown(object sender, KeyRoutedEventArgs e)
{
if(e.Key == Windows.System.VirtualKey.Enter)
{
SendMessage(textBox1.Text);
}
}
private void SendMessage(string message)
{
socketWriter.WriteString(message);
SendPacket();
textBox1.Text = "";
}
}
}
Server Side
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private static int port = 138;
private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
Task.Factory.StartNew(() =>
{
var dataStream = new MemoryStream(1024);
var udpClient = new UdpClient(port);
while (true)
{
if (udpClient.Available > 0)
{
udpClient.BeginReceive(ar =>
{
var clientEndPoint = new IPEndPoint(IPAddress.Any, port);
var bytesReceived = udpClient.EndReceive(ar, ref clientEndPoint);
dataStream.Write(bytesReceived, 0, bytesReceived.Length);
if (bytesReceived.Length > 0)
{
UpdateUI(Encoding.UTF8.GetString(bytesReceived));
UpdateUI(Encoding.ASCII.GetString(bytesReceived));
}
}, null);
}
Thread.Sleep(1);
}
}, _cancellationTokenSource.Token);
}
private void UpdateUI(string message)
{
this.Invoke(new MethodInvoker(delegate
{
this.textBox1.Text += message + Environment.NewLine;
}));
}
private void button1_Click_1(object sender, EventArgs e)
{
byte[] message = Encoding.UTF8.GetBytes(textBox2.Text);
using (var udpClient = new UdpClient())
{
udpClient.Send(message, message.Length, new IPEndPoint(IPAddress.Loopback, port));
}
textBox2.Clear();
}
}
}
The information isn't connecting somewhere in the middle. On both sides nothing breaks. When I test the form by sending information to the loopback it works. I don't know why the information is not reaching the other side. Can you please tell me if I am doing this write and it is suppose to be done this way or can you tell me if this is not possible so I can stop working on it.
I saw a similar question and I answered there, Communicate to PC over USB.
It requires editing the registry, the server code running on the device and I am not sure if the code will run outside of a development environment (I only need this to speed up my workflow and debugging - so its not an issue).
Not possible.
TCP/IP over USB worked OK in Windows Phone 7. In Windows Phone 8 however they removed the functionality.
Seek for other alternatives.
You could use TCP/IP over WiFi, or use BT, or write data to "Documents" and read with MTP COM API, or write data to isolated storage and read it using isetool.exe (this one only works for dev.unlocked devices).

Problems with receiving UDP messages in Metro-Apps

I'm currently working on a project and one of the featured devices is a Windows Tablet. To "connect" it to other devices (like some Raspberry Pi) in the project environment UDP is used to send messages. The Windows Tablet is intended to be some controlling device with soem touch functionality. Therefore I'm writing an App (and the intention of the App is not to put it into the Windows Store). The UDP part in this work is quite painful because I had to do much research since I started with no experience in App programming. More painful than the programming is, that I practically finished the work only to start over again because the App didn't receive UDP anymore.
Here's my code (I removed elements not relevant to the actual problem). I apologize for the bad coding....
App.xaml.cs:
sealed partial class App : Application
{
NetworkInterface ni = new NetworkInterface();
public App()
{
this.InitializeComponent();
this.Suspending += OnSuspending;
ni.MessageReceived += OnMessageReceived;
ni.Connect(new HostName("127.0.0.1"), "5556");
}
private void OnMessageReceived(object sender, MessageReceivedEventArgs e)
{
Debug.WriteLine("Processing");
Debug.WriteLine(e.Message.Data);
}
public static new App Current
{
get { return Application.Current as App; }
}
private DatagramSocket _socket;
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
Update_Timer();
}
DispatcherTimer timer = new DispatcherTimer();
private void Update_Timer()
{
timer.Start();
timer.Interval = new TimeSpan(0,0,0,0,500);
timer.Tick += alive;
}
private void alive(object sender, object e)
{
if (start == 0) {
Debug.WriteLine("App-Startup");
ni.SendMessage("Startup...");
start++;
}
else
{
Debug.WriteLine("App-Alive");
ni.SendMessage("alive");
start++;
}
}
}
This part of code is to send and receive Messages in the backgrond in the whole App.
And a NetworkInterface class:
class NetworkInterface
{
private DatagramSocket _socket;
public bool IsConnected { get; set; }
public NetworkInterface()
{
IsConnected = false;
_socket = new DatagramSocket();
_socket.MessageReceived += OnSocketMessageReceived;
}
public async void Connect(HostName remoteHostName, string remoteServiceNameOrPort)
{
if (IsConnected != true)
{
await _socket.BindServiceNameAsync("5321");
await _socket.ConnectAsync(remoteHostName, remoteServiceNameOrPort);
}
IsConnected = true;
}
public void alive(object sender, object e)
{
Debug.WriteLine("alive");
}
public event EventHandler<MessageReceivedEventArgs> MessageReceived;
private void OnSocketMessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
{
var reader = args.GetDataReader();
var count = reader.UnconsumedBufferLength;
var data = reader.ReadString(count);
Debug.WriteLine(args);
if (MessageReceived != null)
{
var ea = new MessageReceivedEventArgs();
ea.Message = new Message() { Data = data };
ea.RemoteHostName = args.RemoteAddress;
ea.RemotePort = args.RemotePort;
MessageReceived(this, ea);
}
}
DataWriter _writer = null;
public async void SendMessage(string message)
{
if (_writer == null)
{
var stream = _socket.OutputStream;
_writer = new DataWriter(stream);
}
_writer.WriteString(message);
await _writer.StoreAsync();
}
}
The main problems are:
If I dont send something before receiving, I won't be able top get an message.
If I send before I have random Faults at this line:
var reader = args.GetDataReader();
If nothing fails, I'm not able to receive messages from a local Python script (which works) but I can send messages from a local program which the App receives.
Does anyone know how I can fix these problems?
Thanks in advance!

Categories