UWP on Raspberry Pi2 with sockets

Some days ago I tried to take another way for my project on Raspberry. The communication system in I2C was not so strong (as I sayd before) and I started try another aproach: the sockets.

With sockets the real improovement to the communication quality is higher. I tried to communicate from a Raspberry Pi2 toward an Arduino LUA that have a WiFi ESP8622 integrated. For not reinvent the wheel, I’ve loaded a MySensors’ gateway on LUA and I’ve just made a temperature sensor to be sure to receive something on the Raspberry Pi2 soket. But I try to explain better.

First of all

download the sample project from here and in the samples directory find StreamSocket sample. This is the first sample to understand how sockets works in the UWP. But in this sample application there is no sample about how to get data from server, it’s only explained how to send. But I want write and read data from the server and not only send!

The solution is use the StreamSoket in reading mode, but… one step a time 🙂

Let’s start with two properties and some private fields:

[code lang=”csharp” title=”+ Properties”] #region Properties and fields
private readonly string ip;
private readonly int port;
public string Ip { get { return ip; } }
public int Port { get { return port; } }

private StreamSocket socket;
private DataWriter writer;
private DataReader reader;
#endregion
[/code]

they will be able to store the address of our client, where we want to take the data. The private fields (not linked to properties) will be able to store and send our string data (the DataWriters) and the last one is the socket.

Second step we have to connet him.

[code lang=”csharp” title=”+ Connection”]
public async void Connect()
{
try
{
var hostName = new HostName(Ip);
socket = new StreamSocket();
await socket.ConnectAsync(hostName, Port.ToString());
writer = new DataWriter(socket.OutputStream);

Read();
}
catch (Exception ex)
{
}
}
[/code]

And now we can connect to our client in this way:

[code lang=”csharp” title=”+ OnMessageReceived callback”] public event EventHandler<string> OnMessageRecived;
CancellationTokenSource ct = new CancellationTokenSource();

private async void Read()
{
try
{
await Task.Run(async () =&gt;
{
reader = new DataReader(socket.InputStream);
while (true)
{
try
{
reader.InputStreamOptions = InputStreamOptions.Partial;
await reader.LoadAsync(1024);
string data = reader.ReadString(reader.UnconsumedBufferLength);
if (OnMessageRecived != null &amp;&amp; data.Length &gt; 0)
{
OnMessageRecived(this, data);
}

}
catch (Exception ex)
{
await Task.Delay(20);
if (OnError != null)
OnError(ex.Message);
}

}
}, ct.Token);
}
catch (Exception)
{ }
ct = new CancellationTokenSource();
}[/code]

Ok, I have something to explain, right?

So, this routine starts with the declaration of a data reader to allow the application links the soket input to out stream; a new Task to allow the application to run asyncronously and don’t freeze the UI during the data receive.

After i made an infinite while (I know, could be better but this is the first silplified version) that takes bytes from an input stream. To avoid other problems on Raspberry, take only a small quantity of bytes a time. I choose 1024 but up to 2048 I didn’t had any problem.

Here with an event I communicate to external environment that I received something.

Take note that if nothind arrives, nothing moves. The code is still and waiting at line await reader.LoadAsync(1024); until something arrives.

The CancellationToken allows us from extern to stop listening soket.

But go ahead. Now we have to send data.

[code lang=”csharp” title=”+ Send method”]
public async Task<bool> Send(string message)
{
bool ret = false;
try
{
writer.WriteString(message);
//Create the message for send
await writer.StoreAsync();
//Clear for next send
await writer.FlushAsync();
ret = true;
}
catch (Exception ex)
{
}
return ret;
}[/code]

Done. Here we send a string through socket. I think this is quite simple.

Then, take note to don’t leave a catch statement empty! Here is only a sample code and not a production code!

Hope to help you and… Stay tuned!