Unity中的REST(从网络服务器发送消息到统一)

时间:2017-03-31 09:28:20

标签: c# rest unity3d server client

有没有办法让简单的网络服务器向Unity发送消息?

目前,我们在更新方法中使用GET进行UnityWebRequest.Get()。这是代码:

// Update is called once per frame
void Update () {
    StartCoroutine(GetData());
}

IEnumerator GetData()
{
    UnityWebRequest uwr = UnityWebRequest.Get(url);
    yield return uwr.Send();

    if (uwr.isError)
    {
        Debug.Log(uwr.error);
    }else
    {
        Debug.Log((float.Parse(uwr.downloadHandler.text) / 100));
        fnumber = ((float.Parse(uwr.downloadHandler.text) / 100));
        transform.position.Set(oldX, fnumber, oldZ);
    }
}

但是,这会引发此错误:

  

无法解决目的地主持人

我发现了this错误报告,其中说明它已被修复,但似乎并非如此。

那么,有没有办法让服务器向Unity发送消息?

由于

3 个答案:

答案 0 :(得分:3)

扩展我的评论更具描述性和具体性,我的建议是创建一个简单的Thread,作为服务器的沟通管理员。

首先,你必须实现this class来调用Unity的UI线程上的方法。

实现此功能时,只需创建一个类:

public class CommunicationManager
{
    static readonly object syncRoot = new object();

    static CommunicationManager _Instance;
    public static CommunicationManager Instance
    {
        get
        {
            if ( _Instance == null )
            {
                lock ( syncRoot )
                {
                    if ( _Instance == null )
                    {
                        _Instance = new CommunicationManager();
                    }
                }
            }
            return _Instance;
        }
    }

    volatile bool working = false;

    Queue<Message> _messages;

    private CommunicationManager()
    {
        _messages = new Queue<Message>();
        InitializeCommunication();
    }

    void InitializeCommunication()
    {
        Thread t = new Thread(CommunicationLoop);
        t.Start();
    }

    void CommunicationLoop()
    {
        Socket s = null;
        try
        {
            Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            s.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1337));
            working = true;
        }
        catch(Exception ex)
        {
            working = false;
        }
        while ( working )
        {
            lock ( syncRoot )
            {
                while ( _messages.Count > 0 )
                {
                    Message message = _messages.Dequeue();
                    MessageResult result = message.Process(s);
                    result.Notify();
                }
            }
            Thread.Sleep(100);
        }
    }

    public void EnqueueMessage(Message message)
    {
        lock ( syncRoot )
        {
            _messages.Enqueue( message );
        }
    }
}

现在您必须制作MessageMessageResult个对象:

public class Message
{
    const string REQUEST_SCHEME = "{0} {1} HTTP/1.1\r\nHost: {hostname}\r\nContent-Length: 0\r\n\r\n";
    string request;
    Action<MessageResult> whenCompleted;

    public Message(string requestUri, string requestType, Action<MessageResult> whenCompleted)
    {
        request = string.Format(REQUEST_SCHEME, requestType, requestUri);
        this.whenCompleted = whenCompleted;
    }

    public MessageResult Process(Socket s)
    {
        IPEndPoint endPoint = (IPEndPoint)s.RemoteEndPoint;
        IPAddress ipAddress = endPoint.Address;
        request = request.Replace("{hostname}", ipAddress.ToString());
        s.Send(Encoding.UTF8.GetBytes(request));

        // receive header here which should look somewhat like this :
        /*
                HTTP/1.1 <status>
                Date: <date>
                <some additional info>
                Accept-Ranges: bytes
                Content-Length: <CONTENT_LENGTH>
                <some additional info>
                Content-Type: <content mime type>
         */
         // when you receive this all that matters is <CONTENT_LENGTH>
         int contentLength = <CONTENT_LENGTH>;
         byte[] msgBuffer = new byte[contentLength];
         if (s.Receive(msgBuffer) != contentLength )
         {
             return null;
         }

         return new MessageResult(msgBuffer, whenCompleted);
    }
}

最后创建MessageResult对象:

public class MessageResult
{
    Action<MessageResult> notifier;
    byte[] messageBuffer;

    public MessageResult(byte[] message, Action<MessageResult> notifier)
    {
        notifier = notifier;
        messageBuffer = message;
    }

    public void Notify()
    {
        UnityThread.executeInUpdate(() =>
        {
            notifier(this);
        });
    }
}

此方法将在您的主应用程序之外运行,以便不会产生任何冻结等等。

要使用此功能,您只需调用以下内容:

Message message = new Message("/index.html", "GET", IndexDownloaded);
CommunicationManager.Instance.EnqueueMessage(message);

// ...
public void IndexDownloaded(MessageResult result)
{
    // result available here
}

有关更多信息,请阅读有关HTTP的this wikipedia文章。

答案 1 :(得分:0)

这是从RESTful服务器获取请求的简单方法:D。

List

答案 2 :(得分:-3)

尝试使用WWW来代替被破坏的UnityWebRequest。 您使用的是什么版本的统一?