2016-05-18 4 views
1

Ich möchte einige Herzfrequenzwerte, die ich von einem Microsoft Band erhalte, von einer UWP-App an Unity senden. Ich habe derzeit einen funktionierenden TCP-Server in Unity, aber ich konnte nicht scheinen, System.Net.Sockets in UWP zu verwenden. Jeder weiß, wie man einen TCP-Client in der UWP-App erstellt und die Daten an Unity sendet.Wie verbinde ich mich über die Sockets von der UWP-App zum Unity-Spielserver-Socket?

Mein Server-Code lautet wie folgt:

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(); 
} 
} 

Mein UWP-Code ist wie folgt:

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(); 
     }); 
    } 
+1

Ich habe ein paar Fragen für Sie. Da Sie beschlossen haben, 'TcpListner' anstelle des von mir geposteten Unity-Servercodes zu verwenden, was bringt Sie dazu, zu glauben, dass der von Ihnen geschriebene Servercode funktioniert? Haben Sie es getestet, bevor Sie Ihren Client-Code erstellt haben? Ich denke, es wäre Zeitverschwendung, am Client zu arbeiten, ohne den Server zu testen. Lassen Sie es mich wissen, wenn Sie nicht wissen, wie man einen Server testet. – Programmer

+0

@Programmer, ich benutzte den gleichen Server für ein anderes Projekt, das ich mit einem Client verbunden hatte, der die Herzfrequenzwerte von Generic BLE Herzfrequenzmonitoren nahm. Es funktionierte einwandfrei. Das war der Code, den ich vor einem Jahr auf Stakeoverflow gepostet habe: http://stackoverflow.com/questions/30161845/unity-delay-in-sending-the-current-value-when-using-sockets – ChaosEmperor93

+0

Ok gut . Ich denke, ich habe zuvor ähnliche Fragen beantwortet. http://Stackoverflow.com/a/35890916/3785314 Ich habe gerade keinen Code für die Person zur Verfügung gestellt. Jetzt müssen Sie 'TcpClient' in Ihrem UWP-Programm arbeiten lassen? Ich habe noch nie UWP benutzt. Ist der Namespace 'System.Net.Sockets;' in ihm vorhanden? – Programmer

Antwort

1

Nach einigen Forschung, UWP tut nicht haben die System.Net.Sockets; Namespace. Selbst wenn Sie es dort hinzufügen, wird es nach dem Kompilieren nicht ausgeführt. Die neue API heißt StreamSocket Socket. Ich fand ein komplettes Client-Beispiel von here und änderte es ein wenig. Rufen Sie einfach die Verbindungsfunktion auf, senden und lesen Sie Funktionen.

Wichtig zu verstehen ist, dass Sie diesen Test nicht auf demselben PC ausführen können. Ihr Unity-Server und Ihre UWP-App MÜSSEN auf verschiedenen Computern ausgeführt werden. Microsoft macht nicht ermöglichen App, eine Verbindung zu einer anderen App auf dem gleichen Computer bei der Verwendung von 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(); 
      } 
     } 
    } 
} 
+0

Oh Mist. Ich wusste, dass es zu schön war, um wahr zu sein. Das ist leider keine Option für mich. Ich brauche es lokal. Ich werde mein Spiel nach einer Woche oder so präsentieren, aber ich kann keinen Internetzugang garantieren. – ChaosEmperor93

+0

@ ChaosEmperor93 ** Dies ist lokal **. Sie müssen sich mit demselben Router/network.wifi verbinden. Verstehst du das nicht? Und Nein. ** Kein Internet benötigt dafür **. Stellen Sie nur sicher, dass beide mit demselben Netzwerk verbunden sind. Sie können einen einfachen Router kaufen, wenn Sie keinen haben. – Programmer

+0

Leider habe ich den Kommentar gepostet, bevor ich Ihren Kommentar gelesen habe. Problem ist, dass es wahrscheinlich zu Verzögerungen kommen wird, da mein Spiel eine Multiplayer-Funktion hat. Im Multiplayer gibt es eine Option, die Herzfrequenzüberwachung weiterhin zu verwenden.Für die Zukunft funktioniert das nicht gut mit meinen Anforderungen – ChaosEmperor93

Verwandte Themen