Laden...

HTTP Client Server Infrastruktur mit Unity

Erstellt von dekorlp vor 4 Jahren Letzter Beitrag vor 4 Jahren 1.404 Views
D
dekorlp Themenstarter:in
4 Beiträge seit 2010
vor 4 Jahren
HTTP Client Server Infrastruktur mit Unity

Hallo alle zusammen,

ich entwickele aktuell eine Client Server Infrastruktur mit Unity und einem .Net Server basierend auf dem HTTP Protokoll. Der Client (Unity Anwendung) sendet Bilder der Kamera in einem HTTP Post Request an den Server. Der Server lädt das empfangene Bild in eine PictureBox für Debugging Zwecke und sendet anschließend eine JSON Struktur als Response an den Client.
Jedoch habe ich das Problem, das teilweise der Thread nicht ausgeführt wird. Dies ist erkennbar daran, dass sich das Bild in der Picture Box nicht ändert. Sobald ich jedoch mich mit dem Debugger dran hänge, werden die Bilder einwandfrei übertragen. Deshalb vermute ich, dass es an meinen asynchronen Sendebefehl liegt. Mit dem Debugger finde ich nicht die fehlerhafte Stelle. Bei dem Befehl "RunAsync(imgData).RunSynchronously();" habe ich bereits Methoden wie .Start() ausprobiert, aber dies hat auch nicht funktioniert. Ich hoffe ihr könnt mir dabei helfen, ich bin daran inzwischen am Verzweifeln.

Unity Client Skript


public class Example : MonoBehaviour
{
   private WebCamTexture webcamTexures1 = null;
   private bool isCameraActivated = true;

    void Start()
    {
        if (isCameraActivated)
        {
            WebCamDevice[] devices = WebCamTexture.devices;

            if (devices.Length >= 1)
            {
                webcamTexures1 = new WebCamTexture(devices[0].name);
                webcamTexures1.Play();
            }
            else
            {
                webcamTexures1 = null;
            }

            if (devices.Length >= 2)
            {
                webcamTexures2 = new WebCamTexture(devices[1].name);
                webcamTexures2.Play();
            }
            else
            {
                webcamTexures2 = null;
            }
        }
        

    }

    void Update()
    {

        if (webcamTexures1 != null && webcamTexures1.isPlaying)
        {
                Texture2D photo = new Texture2D(webcamTexures1.width, webcamTexures1.height);
                photo.SetPixels(webcamTexures1.GetPixels());
                photo.Apply();
                byte[] imgData = photo.EncodeToJPG(95);
                //Thread th = new Thread(()=>RunAsync(imgData));
                // th.Join();
                RunAsync(imgData).RunSynchronously();
        }
        
    }

    async Task RunAsync(byte[] imgData)
    {
        var response = await client.PostAsync("http://192.168.178.40", new ByteArrayContent(imgData));
                    //Console.WriteLine(response.Content.ReadAsStringAsync().Result);
                
    }

}

Server


        private void Form1_Load(object sender, EventArgs e)
        {
            Thread listenerThread = new Thread(startListener);
            listenerThread.Start();
            
        }

        void startListener()
        {
            string jsonDump = File.ReadAllText("D:\\repository\\PSE\\example.json");

            var prefixes = new List<string>() { "http://+:80/" };
            HttpListener listener = new HttpListener();

            foreach (string s in prefixes)
            {
                listener.Prefixes.Add(s);
            }
            listener.Start();
            Console.WriteLine("Listening...");

            while (true)
            {
                // Note: The GetContext method blocks while waiting for a request.
                    HttpListenerContext context = listener.GetContext();

                HttpListenerRequest request = context.Request;

                //SaveFile(context.Request.ContentEncoding, GetBoundary(context.Request.ContentType), context.Request.InputStream);

                byte[] bufferr = new byte[request.ContentLength64];


                string documentContents;
                Image img;
                using (Stream receiveStream = request.InputStream)
                {
                    using (MemoryStream ms = new MemoryStream())
                    {
                        int read;
                        while ((read = receiveStream.Read(bufferr, 0, bufferr.Length)) > 0)
                        {
                            ms.Write(bufferr, 0, read);
                        }
                        img = Image.FromStream(ms);
                    }
                }


                pictureBox1.Image = img;
                int test = 0;

                //System.IO.File.WriteAllText(@"C:\Users\Dennis\Documents\ank.jpg", html);


                Console.WriteLine($"Recived request for {request.Url}");
                //Console.WriteLine(documentContents);

                // Obtain a response object.
                HttpListenerResponse response = context.Response;
                // Construct a response.
                string responseString = jsonDump;
                byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
                // Get a response stream and write the response to it.
                response.ContentLength64 = buffer.Length;
                System.IO.Stream output = response.OutputStream;
                output.Write(buffer, 0, buffer.Length);
                // You must close the output stream.
                output.Close();
            }
            listener.Stop();
        }
    }

Mit freundlichen Grüßen

Dennis Köhler

W
955 Beiträge seit 2010
vor 4 Jahren

* es wäre sinnvoll die Anwendung asynchron zu entwickeln also das async/await Pattern zu verwenden.
* warum verwendest du kein Asp.Net Core-Server?

D
dekorlp Themenstarter:in
4 Beiträge seit 2010
vor 4 Jahren

Hallo witte,

ich konnte das Problem inzwischen lösen.
Die Lösung war es einfach Unity im Vordergrund zu behalten, das hab ich nicht berücksichtigt, dass der dann den Prozess pausiert. Deswegen hat der auch dann einwandfrei funktioniert, als ich gedebuggt hab. Ich hab den Server, einfach mal auf einen anderen Rechner ausgeführt und dann funktionierte es. So konnte ich auch erkennen, dass sich die PictureBox nicht mehr aktualisiert, wenn ich ein anderes Fenster öffne und Unity somit im Hintergrund ausgeführt wird.

@witte
Danke für deine Antwort,
Ich hab den Aufruf von "RunAsync(imgData).RunSynchronously();" in "RunAsync(imgData)" geändert.
"await RunAsync(imgData);" habe ich bereits probiert, jedoch ist die Render Methode nicht asyncron. Und Await kann man nur in Asynchronen Methoden aufrufen, was zu einem Fehler bei mir führte. Deshalb hatte ich die Funktionalität für das Post Request in die Methode RunAsync ausgelagtert. Meinst du mit Asynchron einen Aufruf über RunAsync().Start()? Aktuell hab ich auch noch auf der Hololens ein Delay von 1-2 Sekunden zwischen der Übertragung des JPG Bildes und der Darstellung im Server. Da muss ich mir noch was überlegen.

Der aktuelle Server wird später ersetzt durch einen Python Server, welcher ein Kollege entwickelt von mir. Den jetzigen Server hab ich implementiert zum testen und debuggen.

Mit freundlichen Grüßen

Dennis Köhler