Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Unity 5 - WWW and HTTP Requests

Discussion in 'Unity 5 Pre-order Beta' started by MaT227, Jan 23, 2015.

  1. MaT227

    MaT227

    Joined:
    Jul 3, 2012
    Posts:
    628
    Hi everyone,

    We are currently using Unity Pro 5.0.0b20 and building our project for WebGL. We were previously using Unity Pro 4.6 and UniWeb from @simonwittber to handle our HTTP Requests because Unity doesn't offer much liberty concerning this topic and it was working really well with UniWeb.
    But it appears that UniWeb is not working anymore on Unity 5 with WebGL builds.

    I would like to know how can I handle advanced HTTP Requests with Unity Pro 5.0.0b20 and WebGL because Unity's WWW request are too simple.

    Thank you !
     
    Blarp likes this.
  2. jonas-echterhoff

    jonas-echterhoff

    Unity Technologies

    Joined:
    Aug 18, 2005
    Posts:
    1,666
    Existing Custom WWW implementation will not work in Unity WebGL, because typically, those are built on top of .NET sockets, which are not available in JavaScript for security reasons.

    We a working on a WWW replacement library for Unity in the future (possibly 5.1), but for now, the only thing you could do is to write your own implementation in JavaScript (based on the XmlHttpRequest class).

    What is it that you need what you cannot do with WWW right now?
     
    androidideas, Meltdown and Blarp like this.
  3. MaT227

    MaT227

    Joined:
    Jul 3, 2012
    Posts:
    628
    Thank you for you fast answer.

    Glad to hear that you are working on a replacement library for WWW. :)

    Could tell me more about a JavaScript implementation ? This might not be done inside Unity right ? How would you send your request using Unity and an external request engine ?

    At the moment, simple GET and POST requests can be handled but if you are looking for more advanced requests or maybe custom GET and POST requests, it's simply not possible.
    I don't have any specific example because we faced the limit of the WWW class a long time ago and we switched to an unrestricted product like UniWeb.
    From what I remember, there are too much restriction and not enough liberty concerning the building of requests in terms of headers, responses data, and http request types.
    I am sorry that I can't give you more explanations, maybe other users might have relevant examples.

    A JSON reader/writer and extractor would also be really useful ! :)

    Any idea about RestSharp, it is a well known REST and HTTP API Client. Do you know if it should work with WebGL ?

    Thank you again.
     
    Last edited: Jan 23, 2015
  4. mtalbott

    mtalbott

    Joined:
    Dec 21, 2011
    Posts:
    125
    I'll throw my hat in here.

    The ability to add a header to GET requests is increasingly becoming required by several RESTful api's for authentication. There are a lot but Twitter is an obvious example. Back in the day you could request tweets without any authentication but they now require an api key in the GET header. I have never found a working solution with WWW. My workaround to this day is to request a PHP on my server that then does the real request to twitter. It would be great if WWW could handle this situation.
     
    DanSuperGP likes this.
  5. MaT227

    MaT227

    Joined:
    Jul 3, 2012
    Posts:
    628
    Thank you for this nice example. :)
     
    DanSuperGP likes this.
  6. jonas-echterhoff

    jonas-echterhoff

    Unity Technologies

    Joined:
    Aug 18, 2005
    Posts:
    1,666
    So, yes, setting headers and methods will be supported in our upcoming WWW replacement API. Until we have that, the only way to get this to work in Unity WebGL right now is to write your own implementation using the XmlHttpRequest class in JavaScript, which has support for all these features (but some restrictions on cross domain resource access for security, see WebGL chapter in Unity 5 docs to learn more about this).
     
    twobob and androidideas like this.
  7. yuliyF

    yuliyF

    Joined:
    Nov 15, 2012
    Posts:
    197
  8. MaT227

    MaT227

    Joined:
    Jul 3, 2012
    Posts:
    628
    According to the Unity 5 documentation, it's not possible to use any System.Net networking classes.
    So, I think that we can forget any .NET implementation. I don't know how RestSharp is built and if it could be a reliable solution.
    And to be honest I have some difficulty about imagining how we can work now with XmlHttpRequest.
     
  9. yuliyF

    yuliyF

    Joined:
    Nov 15, 2012
    Posts:
    197
  10. MaT227

    MaT227

    Joined:
    Jul 3, 2012
    Posts:
    628
    It doesn't seem that you can access the documentation unless you have Unity 5 Beta :(
     
  11. yuliyF

    yuliyF

    Joined:
    Nov 15, 2012
    Posts:
    197
    oh understood.. It's not a big problem a few hours and I install it)
     
  12. yuliyF

    yuliyF

    Joined:
    Nov 15, 2012
    Posts:
    197
    in 5.0 beta 21 with class WWW - all ok, send and get data with out an any changes
     
    Last edited: Jan 27, 2015
  13. MaT227

    MaT227

    Joined:
    Jul 3, 2012
    Posts:
    628
    It doesn't seem that the WWW class has been improved in the Unity 5.0.21b. Or maybe I missed something ?
     
  14. Meltdown

    Meltdown

    Joined:
    Oct 13, 2010
    Posts:
    5,822
    As Jonas said, they are looking to provide a replacement in Unity 5.1
     
  15. MaT227

    MaT227

    Joined:
    Jul 3, 2012
    Posts:
    628
    Yep that's what I understood but according to @yuliyF I thought that there was a little surprise :)
     
  16. bsterling250DI

    bsterling250DI

    Joined:
    Sep 25, 2014
    Posts:
    78
    @jonas echterhoff : I've noticed you mention implementing the XmlHttpRequest class in Javascript now in a couple different threads, any chance you could share a small code example of how to do this? for example a simple GET request?
     
  17. MaT227

    MaT227

    Joined:
    Jul 3, 2012
    Posts:
    628
    I agree, this could be very interesting.
     
  18. jonas-echterhoff

    jonas-echterhoff

    Unity Technologies

    Joined:
    Aug 18, 2005
    Posts:
    1,666
    We use the XmlhttpRequest class ourselves to implement WWW in Unity. You can look at the jslibf file we use if you look inside Unity in PlaybackEngines/WebGLSupport/BuildTools/lib/WebRequest.js - you'd just need to write C# functions to call these for a custom solution.
     
    androidideas likes this.
  19. MaT227

    MaT227

    Joined:
    Jul 3, 2012
    Posts:
    628
    @jonas echterhoff, I've made some tests and I can easily communicate with the browser javascript but I can't achieve to communicate with your WebRequest.js file.

    Here is the classic way to do it : WebGL | WebPlayer: Interacting with browser scripting

    I've added a simple function and tried to call it from the WebGL build but it simply fails.
    WebRequest.js
    Code (JavaScript):
    1. function WebRequestHello(arg)
    2. { alert(arg); }
    3. var LibraryWebRequestWebGL = { ...
    WebGL Unity C#
    Code (CSharp):
    1. Application.ExternalCall("WebRequestHello", "WebRequest - Hello");
    How can I call those function from the WebGL build ? Can you give some precisions about how can we handle this ?
    Thanks a lot !
     
    Last edited: Feb 4, 2015
  20. Nik0s

    Nik0s

    Joined:
    Aug 16, 2013
    Posts:
    9
  21. Claytonious

    Claytonious

    Joined:
    Feb 16, 2009
    Posts:
    904
    Since we're airing feedback on the WWW implementation, another chronic problem we have with WWW is that if you get an error response, such as a "400 bad request", you cannot access the body of the response! The WWW class eats it. For example, a service might return a "400" response along with text explaining the problem, but we can't see that text via www.text or anything else. WWW swallows those unless the response status code is 2xx I guess. That really clobbers proper use of many REST services.

    Always let us see the response!
     
  22. MaT227

    MaT227

    Joined:
    Jul 3, 2012
    Posts:
    628
    Thank you for the link, I didn't know that we could look at the Unity 5 beta documentation online. :)
    And yes, I've followed this method.
    Thank you for the package but to be honest, I am not very comfortable with networking and for me WebSockets are different from HTTP requests and I don't see how can I handle HTTP requests like PUT, GET, POST, UPDATE, DELETE, etc. with WebSockets.
     
  23. Nik0s

    Nik0s

    Joined:
    Aug 16, 2013
    Posts:
    9
    I only pointed to the websockets package to see how the Javascript Plugin method was implemented i.e. [DllImport("__Internal")], etc

    Try renaming PlaybackEngines/WebGLSupport/BuildTools/lib/WebRequest.js to jslib and using that as your Javascript Plugin
     
  24. MaT227

    MaT227

    Joined:
    Jul 3, 2012
    Posts:
    628
    Oh right, I'll take a look at it.
     
  25. Gizmoi

    Gizmoi

    Joined:
    Jan 9, 2013
    Posts:
    327
    This is a major gripe for us as well. We've had to write a server that returned errors as 200 with a secondary error code inside the body.
     
    Claytonious likes this.
  26. bdovaz

    bdovaz

    Joined:
    Dec 10, 2011
    Posts:
    1,053
    - Event based (OnProgress, OnCompleted...) although we have implemented a www wrapper that allows this.
    - You can't have a request other than GET or POST. I would like to have a PUT request for example.
    - Allow to set a timeout.
     
    Claytonious likes this.
  27. MaT227

    MaT227

    Joined:
    Jul 3, 2012
    Posts:
    628
    Hey everyone,

    I am always trying to implement the PlaybackEngines/WebGLSupport/BuildTools/lib/WebRequest.js in my project as a jslib file.

    WebRequest.cs
    Code (CSharp):
    1. using UnityEngine;
    2. using System;
    3. using System.Collections;
    4. using System.Runtime.InteropServices;
    5.  
    6. public class WebRequest
    7. {
    8.     public Uri _url;
    9.     public int _requestId = 0;
    10.  
    11.     [DllImport("__Internal")]
    12.     private static extern int   JS_WebRequest_Create(IntPtr url, IntPtr method);
    13.     [DllImport("__Internal")]
    14.     private static extern void  JS_WebRequest_SetTimeout(int request, float timeout);
    15.     [DllImport("__Internal")]
    16.     private static extern void  JS_WebRequest_SetRequestHeader(int request, IntPtr header, IntPtr value);
    17. //    [DllImport("__Internal")]
    18. //    private static extern void  JS_WebRequest_SetHandler(int request, ? arg, ? onresponse);
    19.     [DllImport("__Internal")]
    20.     private static extern void  JS_WebRequest_Send(int request, IntPtr ptr, int length);
    21. //    [DllImport("__Internal")]
    22. //    private static extern int    JS_WebRequest_GetResponseHeaders(int request, ? buffer, int buffersize);
    23. //    [DllImport("__Internal")]
    24. //    private static extern int    JS_WebRequest_GetStatusLine(int request, ? buffer, int buffersize);
    25.     [DllImport("__Internal")]
    26.     private static extern void    JS_WebRequest_Abort(int request);
    27.     [DllImport("__Internal")]
    28.     private static extern void     JS_WebRequest_Release(int request);
    29.  
    30.     public WebRequest(Uri url, string method)
    31.     {
    32.         _url = url;
    33.         IntPtr urlPtr = Marshal.StringToHGlobalUni(_url.ToString());
    34.         IntPtr methodPtr = Marshal.StringToHGlobalUni(method);
    35.         _requestId = JS_WebRequest_Create(urlPtr, methodPtr);
    36.         Marshal.FreeHGlobal(urlPtr);
    37.         Marshal.FreeHGlobal(methodPtr);
    38.     }
    39. }

    WebRequestTest.cs
    Code (CSharp):
    1. using UnityEngine;
    2. using System;
    3. using System.Collections;
    4. using System.Collections;
    5.  
    6. public class WebRequestTest : MonoBehaviour {
    7.  
    8.     public WebRequest request = null;
    9.  
    10.     void Start () {}
    11.  
    12.     void Update ()
    13.     {
    14.         if (Input.GetKeyDown(KeyCode.Space) && request == null)
    15.         {
    16.             request = new WebRequest(new Uri("http://myURL/myAPI/something"), "GET");
    17.         }
    18.     }
    19. }
    And for the moment I am having the error :

    Edit: By using StringToHGlobalUni instead of StringToHGlobalAnsi I don't get the crash.

    I also have some difficulties about create the WebRequest interface of the jslib as I don't know the type of some js variables.

    I would be glad if we found together a solution that might help us waiting for Unity 5 implementation.
     
    Last edited: Feb 12, 2015
  28. MaT227

    MaT227

    Joined:
    Jul 3, 2012
    Posts:
    628
    @jonas echterhoff, it would be very useful if you or somebody else could provide a sample file for the interface of the WebRequest.jslib.
    Because I just feel like reinventing the wheel and there is no advantage of spending so much time for something which is temporary in my opinion.

    Thank you.
     
  29. MaT227

    MaT227

    Joined:
    Jul 3, 2012
    Posts:
    628
    Any help ?