在 Windows Phone 8 上的 Unity 中发出发布请求

问题描述 投票:0回答:4

我正在尝试从 Unity 平台在 Windows Phone 8 上执行发布请求。我不想使用统一的 WWW 方法,因为这会阻止渲染(并且不是线程安全的)。

以下代码可以在编辑器和 Android 上运行,但是在为 WP8 构建它时出现以下错误。

System.Byte[] System.Net.WebClient::UploadData(System.String,System.String,System.Byte[])` 在目标框架中不存在。

这个错误的原因解释在这里

这是因为 Windows Phone 8 使用一种不同风格的 .NET,称为 .NET for Windows Phone,它缺少其他平台上可用的一些类型。您必须用不同的类型替换这些类型或自己实现它们。 - http://docs.unity3d.com/Manual/wp8-faq.html

这是我的代码

using (WebClient client = new WebClient())
{
    client.Encoding = System.Text.Encoding.UTF8;
    client.Headers[HttpRequestHeader.ContentType] = "application/json";

    byte[] requestData = new byte[0];
    string jsonRequest = "{}";
    if (data != null) 
    {
        string tempRequest = Converter.SerializeToString (data);
        jsonRequest = "{\"Data\": \"" + tempRequest + "\"}";

        requestData = System.Text.Encoding.UTF8.GetBytes(jsonRequest);
    }

    // below line of code is the culprit    
    byte[] returnedData = client.UploadData(url, "POST", requestData);

    if(returnedData.Length > 0)
    {
        // do stuff
    }
}

我也尝试过WebRequests,但是GetResponse()破坏了它,并且HttpClient不存在。

那么,如何在 Windows Phone 8 上在 Unity 中发布数据,而不使用 WWW?

根据评论请求更新 - WebRequests

此代码使用 HttpWebRequest 在编辑器和 Android 上运行,但在 Windows Phone 上会引发代码下面列出的错误。

var request = (System.Net.HttpWebRequest) System.Net.WebRequest.Create(url); 
request.ContentType = "application/json";
request.Method = "POST";

var sw = new System.IO.StreamWriter(request.GetRequestStream(), System.Text.Encoding.UTF8);

sw.Write(jsonRequest); // jsonRequest is same variable as in above code, string with json object.
sw.Close();

var re = request.GetResponse();

string resultString = "";
using (var outputStream = new System.IO.StreamReader(re.GetResponseStream(), System.Text.Encoding.UTF8))
{
    resultString = outputStream.ReadToEnd();
}

if(resultString.Length > 0)
{}

错误1:

错误:目标框架中不存在方法

System.IO.Stream System.Net.HttpWebRequest::GetRequestStream()

错误2:

System.Net.WebResponse System.Net.HttpWebRequest::GetResponse()
目标框架中不存在。

更新更多细节 - UploadStringAsync

使用此代码发出异步请求,它在编辑器中再次运行良好,但在 WP8 上会引发错误。

bool isCompleted = false;
byte[] returnedData = null;
client.UploadDataCompleted += 
   new UploadDataCompletedEventHandler((object sender, UploadDataCompletedEventArgs e) => 
{
        Debug.Log("return event");
        returnedData = e.Result;
        isCompleted =true;
});

Debug.Log("async call start");
client.UploadDataAsync(new Uri(url), requestData);

while(isCompleted == false){
    Thread.Sleep(100);
}

if(returnedData.Length > 0)
{}

错误1

方法

System.Void System.Net.WebClient::add_UploadDataCompleted(System.Net.UploadDataCompletedEventHandler)
在目标框架中不存在。

错误2

错误:目标框架中不存在方法

System.Void System.Net.WebClient::UploadDataAsync(System.Uri,System.Byte[])

错误3

错误:目标框架中不存在类型

System.Net.UploadDataCompletedEventArgs

错误4

错误:目标框架中不存在方法

System.Byte[] System.Net.UploadDataCompletedEventArgs::get_Result()

c# unity-game-engine windows-phone-8
4个回答
1
投票

我不知道 Unity 对您施加的任何潜在限制,但 Windows Phone 8 有

WebClient.UploadStringAsync
方法
WebClient.UploadStringCompleted
事件
来执行此操作。

HttpWebRequest
也应该可以工作(同样,我不知道任何 Unity 限制 - 请参阅上面的评论以获取澄清)。


1
投票

使用下面的代码在 Windows Phone 上使用它。在 Android 和 WP8 上的编辑器中编译并运行(耶!)。 iOS 上还没试过。

还在这里写了一篇关于它的文章:创建适用于所有平台(甚至是 WP8)的统一 Web 请求

/// <summary>
/// Make post request to url with given paramaters
/// </summary>
/// <param name="url">URL to post data to http://server.com/method </param>
/// <param name="data">{ Data: data }</param>
/// <returns>string server response</returns>
public string PostData(string url, string data)
{
    // json request, hard coded right now but use "data" paramater to set this value.
    string jsonRequest = "{\"Data\": \"data\"}"; // the json request

    var request = System.Net.WebRequest.Create(url) as System.Net.HttpWebRequest;

    // this could be different for your server
    request.ContentType = "application/json"; 

    // i want to do post and not get
    request.Method = "POST"; 

    // used to check if async call is complete
    bool isRequestCallComplete = false;

    // store the response in this
    string responseString = string.Empty;

    request.BeginGetRequestStream(ar =>
    {
        var requestStream = request.EndGetRequestStream(ar);
        using (var sw = new System.IO.StreamWriter(requestStream))
        {
            // write the request data to the server
            sw.Write(jsonRequest);

            // force write of all content 
            sw.Flush();
        }

        request.BeginGetResponse(a =>
        {
            var response = request.EndGetResponse(a);
            var responseStream = response.GetResponseStream();
            using (var sr = new System.IO.StreamReader(responseStream))
            {
                // read in the servers response right here.
                responseString = sr.ReadToEnd();
            }
            // set this to true so the while loop at the end stops looping.
            isRequestCallComplete = true;
        }, null);

    }, null);

    // wait for request to complete before continuing
    // probably want to add some sort of time out to this 
    // so that the request is stopped after X seconds.
    while (isRequestCallComplete == false) { Thread.Sleep(50); }

    return responseString;
}

0
投票

您无法从 Unity 中使用这些框架,因为它们是线程/异步/使用另一个版本的 .Net

简而言之:

  • Unity 在仅接受 .Net 3.5 的 mono 版本上运行
  • Unity 不允许您启动线程、任务或任何接近真正异步的东西
  • 不过你可以实现这些。

要在 Windows Phone 上执行此操作,您需要创建一个类库(实际上是两个),Unity 称之为插件

那么为什么有两个 dll?

因为编辑器需要一个模型 dll(如果您也想在桌面上实现它,则需要实际的 dll),该模型实现与 Windows Phone 上兼容的 dll 相同的接口。

要明确:

  • 编辑器的 dll(在资源/插件中)需要兼容 .Net 3.5 和桌面
  • 放置在 Assets/plugins/WP8 中的 dll 需要兼容 Windows Phone .Net 子集(我记得你可以是没有 pb 的 .Net 4.5)

所以你应该在dll中实现该功能,然后统一引用它,最后直接调用它。

所有内容都在这里解释:http://docs.unity3d.com/Manual/wp8-plugins-guide-csharp.html

它比看起来更简单。


0
投票

我知道你说过你不想使用 WWW 类,但你给出的理由在我看来没有意义。

如果您使用协程检查“.isDone”标志,而不是使用 Thread.Sleep() 检查它,它不会阻止渲染并且是线程安全的(因为 Unity 只允许您在单个线程上访问其信息)。

如果您想访问另一个线程上的返回数据,您只需在主统一线程中读取该数据,然后将其传递到您想要使用它的任何线程。

Unity 的设计全部在单个线程上运行,以使经验不足的程序员的工作更轻松。 虽然您应该能够使用 .NET 线程创建多个线程,但您将无法直接与任何 Unity 组件通信,但您可以将数据传递回 Unity 并等待 Update 或 Unity 的其他调用来使用数据。我知道这并不能完全回答您的问题,但如果您无法解决它,我认为值得再次查看 WWW 类以及使用它的最佳实践。

© www.soinside.com 2019 - 2024. All rights reserved.