Reputation: 117
I would like to send some heart rate values I receive from a Microsoft Band from a UWP app to Unity. I have currently a working Tcp Server in Unity but I could not seem to use System.Net.Sockets in UWP. Anyone knows how to make a tcp client on the UWP app and send the data to Unity?
My server code is as follows:
using UnityEngine;
using System.Collections;
using System.Net.Sockets;
using System.IO;
using System.Net;
using System.Threading;
public class Server {
public static TcpListener listener;
public static Socket soc;
public static NetworkStream s;
public void StartService () {
listener = new TcpListener (15579);
listener.Start ();
for(int i = 0;i < 1;i++){
Thread t = new Thread(new ThreadStart(Service));
t.Start();
}
}
void Service () {
while (true)
{
soc = listener.AcceptSocket ();
s = new NetworkStream (soc);
StreamReader sr = new StreamReader (s);
StreamWriter sw = new StreamWriter (s);
sw.AutoFlush = true;
while(true)
{
string heartrate = sr.ReadLine ();
if(heartrate != null)
{
HeartRateController.CurrentHeartRate = int.Parse(heartrate);
Debug.Log(HeartRateController.CurrentHeartRate);
}
else if (heartrate == null)
{
break;
}
}
s.Close();
}
}
void OnApplicationQuit()
{
Debug.Log ("END");
listener.Stop ();
s.Close();
soc.Close();
}
}
My UWP code is as follows:
public IBandInfo[] pairedBands;
public IBandClient bandClient;
public IBandHeartRateReading heartreading;
public MainPage()
{
this.InitializeComponent();
ConnectWithBand();
}
public async void ConnectWithBand()
{
pairedBands = await BandClientManager.Instance.GetBandsAsync();
try
{
if (pairedBands.Length > 0)
{
bandClient = await BandClientManager.Instance.ConnectAsync(pairedBands[0]);
}
else
{
return;
}
}
catch (BandException ex)
{
textBlock.Text = ex.Message;
}
GetHeartRate();
}
public async void GetHeartRate()
{
IEnumerable<TimeSpan> supportedHeartBeatReportingIntervals = bandClient.SensorManager.HeartRate.SupportedReportingIntervals;
bandClient.SensorManager.HeartRate.ReportingInterval = supportedHeartBeatReportingIntervals.First<TimeSpan>();
bandClient.SensorManager.HeartRate.ReadingChanged += this.OnHeartRateChanged;
try
{
await bandClient.SensorManager.HeartRate.StartReadingsAsync();
}
catch (BandException ex)
{
throw ex;
}
Window.Current.Closed += async (ss, ee) =>
{
try
{
await bandClient.SensorManager.HeartRate.StopReadingsAsync();
}
catch (BandException ex)
{
// handle a Band connection exception
throw ex;
}
};
}
private async void OnHeartRateChanged(object sender, BandSensorReadingEventArgs<IBandHeartRateReading> e)
{
var hR = e.SensorReading.HeartRate;
await textBlock.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Low, () =>
{
textBlock.Text = hR.ToString();
});
}
Upvotes: 2
Views: 4371
Reputation: 125245
After doing some research, UWP does not have the System.Net.Sockets;
namespace. Even if you manage to add it there, it won't run after compiling. The new API is called StreamSocket socket. I found a full client example from here and modified it a little bit. Just call the connect function, send and read functions.
Important thing to understand is that you can't run this test on the-same PC. Your Unity server and UWP App MUST be running on different computers. Microsoft does not allow App to connect to another app on the-same computer when using UWP.
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Windows.Networking;
using Windows.Networking.Sockets;
using Windows.Storage.Streams;
namespace MyUniversalApp.Helpers
{
public class SocketClient
{
StreamSocket socket;
public async Task connect(string host, string port)
{
HostName hostName;
using (socket = new StreamSocket())
{
hostName = new HostName(host);
// Set NoDelay to false so that the Nagle algorithm is not disabled
socket.Control.NoDelay = false;
try
{
// Connect to the server
await socket.ConnectAsync(hostName, port);
}
catch (Exception exception)
{
switch (SocketError.GetStatus(exception.HResult))
{
case SocketErrorStatus.HostNotFound:
// Handle HostNotFound Error
throw;
default:
// If this is an unknown status it means that the error is fatal and retry will likely fail.
throw;
}
}
}
}
public async Task send(string message)
{
DataWriter writer;
// Create the data writer object backed by the in-memory stream.
using (writer = new DataWriter(socket.OutputStream))
{
// Set the Unicode character encoding for the output stream
writer.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8;
// Specify the byte order of a stream.
writer.ByteOrder = Windows.Storage.Streams.ByteOrder.LittleEndian;
// Gets the size of UTF-8 string.
writer.MeasureString(message);
// Write a string value to the output stream.
writer.WriteString(message);
// Send the contents of the writer to the backing stream.
try
{
await writer.StoreAsync();
}
catch (Exception exception)
{
switch (SocketError.GetStatus(exception.HResult))
{
case SocketErrorStatus.HostNotFound:
// Handle HostNotFound Error
throw;
default:
// If this is an unknown status it means that the error is fatal and retry will likely fail.
throw;
}
}
await writer.FlushAsync();
// In order to prolong the lifetime of the stream, detach it from the DataWriter
writer.DetachStream();
}
}
public async Task<String> read()
{
DataReader reader;
StringBuilder strBuilder;
using (reader = new DataReader(socket.InputStream))
{
strBuilder = new StringBuilder();
// Set the DataReader to only wait for available data (so that we don't have to know the data size)
reader.InputStreamOptions = Windows.Storage.Streams.InputStreamOptions.Partial;
// The encoding and byte order need to match the settings of the writer we previously used.
reader.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8;
reader.ByteOrder = Windows.Storage.Streams.ByteOrder.LittleEndian;
// Send the contents of the writer to the backing stream.
// Get the size of the buffer that has not been read.
await reader.LoadAsync(256);
// Keep reading until we consume the complete stream.
while (reader.UnconsumedBufferLength > 0)
{
strBuilder.Append(reader.ReadString(reader.UnconsumedBufferLength));
await reader.LoadAsync(256);
}
reader.DetachStream();
return strBuilder.ToString();
}
}
}
}
Upvotes: 2