Использование веб-сокетов через простые веб-сокеты для актива webgl в unity3d может подключаться, но не может передавать сообщения

У меня просто возникла проблема на моем Mac, пытающемся отправить строки через веб-сокеты, используя этот https://www.assetstore.unity3d.com/en/#!/content/38367

Много адаптированного кода ниже отсюда, в основном http://www.codepool.biz/how-to-implement-a-java-websocket-server-for-image-transmission-with-jetty.html и веб-сокет Sharp echotest пример.

Я могу подключиться, но в окне консоли моего сервера Jetty нет никаких признаков строк (на сервере ws, работающем в java (eclipse)).

Я в основном просто пытаюсь отправить «1» на свой сервер через соединение через веб-сокет с редактором единства (5) на данный момент, чтобы побудить сервер начать отправлять файлы PNG, закодированные как массивы байтов, поэтому я могу вернуть их обратно вместе в сценарии C# и применить их к текстуре.

это скрипт, я хочу прикрепить его к игровому объекту, такому как самолет или куб, и отображать обновляемые изображения, отправленные через веб-сокет с моего сервера Jetty, но на данный момент я просто застрял, пытаясь отправить сообщение и посмотрите, как он появляется в моем окне консоли eclipse.

using UnityEngine;
 using System.Collections;
 using System;

 public class socketTexture : MonoBehaviour {

     // Use this for initialization
     IEnumerator Start () {
         WebSocket w = new WebSocket(new Uri("ws://192.168.0.149:8080/"));
         yield return StartCoroutine(w.Connect());
         Debug.Log ("Connected");
         w.SendString("I'm client");
         w.SendString("1");
         while (true)
         {
             byte[] reply = w.Recv();
             if (reply != null)
             {
                 Debug.Log ("Received: "+reply);
                 var tex = new Texture2D(300, 300, TextureFormat.PVRTC_RGBA4, false);
                 // Load data into the texture and upload it to the GPU.
                 tex.LoadRawTextureData(reply);
                 tex.Apply();
                 // Assign texture to renderer's material.
                 GetComponent<Renderer>().material.mainTexture = tex;
             }
             if (w.Error != null)
             {
                 Debug.LogError ("Error: "+w.Error);
                 break;
             }
             yield return 0;
         }
         w.Close();
     }
 }

... И соответствующий код с сервера причала, но это работает, я протестировал его с некоторым javascript, и я могу загрузить PNG обратно в окно браузера, так что я определенно делаю что-то не так в Unity.

@OnWebSocketMessage  //part request from websocket client (remote browser)
     public void onMessage( String message) {
         System.out.println("message");
         if (message.equals("1") || message.equals("2") || message.equals("3") || message.equals("4") ) {
             System.out.println("Part " + message + " joined");  
             System.out.println( UIMain.usersPath + "/" + message + ".png" );
             final String testVar = ( UIMain.usersPath + "/" + message + ".png" );
             task = new FileWatcher( new File(testVar) ) {
                 protected void onChange( File file ) {
                     // here we code the action on a change
                     System.out.println( "File "+ file.getName() +" has changed!" );
                     try {            
                         File f = new File(testVar);
                         BufferedImage bi = ImageIO.read(f);
                         ByteArrayOutputStream out = new ByteArrayOutputStream();
                         ImageIO.write(bi, "png", out);
                         ByteBuffer byteBuffer = ByteBuffer.wrap(out.toByteArray());
                         mSession.getRemote().sendBytes(byteBuffer);
                         out.close();
                         byteBuffer.clear();
                         }
                            catch (IOException e) {
                                e.printStackTrace();
                         }    
             }
         };
         Timer timer1 = new Timer(); {
         timer1.schedule(task , new Date(), 40 );
         }

         }
         else if (message.equals( "0")) {
             zerocounter = zerocounter + 1;
             if (zerocounter >= 2) {
                 task.cancel();
             }
         }
         else if (message.equals( "Hi there, client here")) {
             System.out.println( "Client says: " + message );
         }
     }

Любая помощь будет очень признательна, я скрывался здесь много лет, надеюсь, скоро выйду на сцену, где я тоже смогу немного помочь другим. Бенедикт

Изменить: это сообщение об ошибке моей консоли в Unity

FormatException: недопустимая длина. System.Convert.FromBase64String (System.String s) (в /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/Convert.cs:146) EchoTest+c__Iterator0.MoveNext ( ) (в активах/примере/EchoTest.cs:11)

Я почти уверен, что проблема возникает из-за острого веб-сокета для webgl. Мне нужно отправить сообщение в виде массива байтов.


person Benedict Carey    schedule 09.12.2015    source источник
comment
Мой собственный прогресс заключался в том, чтобы передать байт-код файла PNG в Unity через соединение через веб-сокет и отобразить в виде текстуры! последний трюк теперь состоит в том, чтобы заставить Unity отправить строку обратно на мой сервер, и, к сожалению, похоже, что я не могу разобраться с форматированием, используемым websocket Sharp. используя websocket.send в javascript, он работает. когда я использую websocket.SendString() в websocket Sharp, сервер не видит сообщения. застрял на этом на несколько дней, любая помощь будет оценена по достоинству :)))   -  person Benedict Carey    schedule 09.12.2015
comment
Можете ли вы показать больше о настройке конечной точки WebSocket на сервере? Просто @OnMessage недостаточно. Кроме того, какие журналы вы видите?   -  person Joakim Erdfelt    schedule 09.12.2015
comment
Это почти то же самое, что и в приведенной выше ссылке codepool.biz/, здесь нельзя вставить много кода в поле ответа   -  person Benedict Carey    schedule 09.12.2015
comment
Добавьте @OnWebSocketConnect и убедитесь, что эта конечная точка вообще используется. Ваша реализация @OnWebSocketConnect может даже отправить сообщение TEXT/BINARY вашему клиенту. Если это даже не показывает активность, то вы даже не подключены к этой конечной точке WebSocket.   -  person Joakim Erdfelt    schedule 09.12.2015
comment
Я установил соединение с клиентом javascript, и он отлично работает в двух направлениях (в основном тот, который был реализован Десмондом Шоу). Мне также удалось передать массивы байтов моему клиенту Unity после завершения рукопожатия, но я регистрирую соединение с этого IP-адреса на своем Java-сервере и не получаю никаких последующих сообщений с этого IP-адреса. Я не придумал, как проверить на стороне клиента, отправляется ли сообщение из моего приложения Unity, потому что я использую этот простой веб-сокет для ресурса web gl, который несколько упрощает сценарий. Я могу просто отключиться и снова подключиться.   -  person Benedict Carey    schedule 09.12.2015
comment
Я только что протестировал клиент с этим, и он работает websocket.org/echo.html, поэтому он должно быть, недостаток в реализации моего сервера, как вы говорите   -  person Benedict Carey    schedule 09.12.2015
comment
Возможно, это просто неправильная конфигурация вашего Server. Реализация codepool.biz до смешного проста, без контекстов, 1 обработчик, без поддержки http, очень негибкое использование. Если вы что-то измените, вам придется переосмыслить настройку Server и то, как вы подключаетесь.   -  person Joakim Erdfelt    schedule 09.12.2015


Ответы (1)


Итак, Йоаким Эрдфельт был прав, сервер не был настроен для обработки сообщений типа Byte[]. Вот что я добавил, чтобы исправить это:

@OnWebSocketMessage
public void onMessage(byte[] buffer, int offset, int length) throws UnsupportedEncodingException {
      System.out.println(buffer);
      String sFclientOutStr = new String(buffer, "UTF-8");
        sFclientOut = Integer.parseInt(sFclientOutStr);
      System.out.println(sFclientOut);
        if ((sFclientOut > 0) & (sFclientOut < 500)) {
            System.out.println("Part " + sFclientOut + " joined");  
            System.out.println( UIMain.usersPath + "/" + sFclientOutStr + ".png" );
            final String testVar = ( UIMain.usersPath + "/" + sFclientOutStr + ".png" );
            task = new FileWatcher( new File(testVar) ) {
                protected void onChange( File file ) {
                    // here we code the action on a change
                    System.out.println( "File "+ file.getName() +" has changed!" );
                    try {           
                        File f = new File(testVar);
                        BufferedImage bi = ImageIO.read(f);
                        ByteArrayOutputStream out = new ByteArrayOutputStream();
                        ImageIO.write(bi, "png", out);
                        ByteBuffer byteBuffer = ByteBuffer.wrap(out.toByteArray());
                        mSession.getRemote().sendBytes(byteBuffer);
                        out.close();
                        byteBuffer.clear();
                        }
                        catch (IOException e) {
                            e.printStackTrace();
                        }   
            }
        };
        Timer timer1 = new Timer(); {
        timer1.schedule(task , new Date(), 40 );
        }

        }
        else if (sFclientOutStr.equals("0")) {
            zerocounter = zerocounter + 1;
            if (zerocounter >= 2) {
                task.cancel();
            }
        }
        else if (sFclientOutStr.equals( "I'm client")) {
            System.out.println( "Client says: " + sFclientOutStr );
        }

}

Эти ссылки помогли мне объяснить это http://www.programcreek.com/java-api-examples/index.php?api=org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage

http://www.eclipse.org/jetty/documentation/current/jetty-websocket-api-annotations.html

person Benedict Carey    schedule 10.12.2015