Search Unity

Best HTTP Released

Discussion in 'Assets and Asset Store' started by BestHTTP, Sep 11, 2013.

  1. jhnissin

    jhnissin

    Joined:
    Sep 7, 2015
    Posts:
    27
    @BestHTTP

    I have been adding more debug logging to different parts of the TLS implementation and I noticed that every now and then I get this sort of an error. Could this be connected to the TLS error that I previously reported?

    HTTPUtilsException: HTTPUtils HTTPRequestAsObservable: Request to ****** finished with unexpected error.
    Error message: Write failure
    Stack trace: at System.Net.Sockets.NetworkStream.Write (System.Byte[] buffer, Int32 offset, Int32 size) [0x00000] in <filename unknown>:0
    at Org.BouncyCastle.Crypto.Tls.RecordStream.WriteRecord (Byte type, System.Byte[] plaintext, Int32 plaintextOffset, Int32 plaintextLength) [0x0012a] in /Users/jnis/Documents/code/work/helsinki-airport-unity/Assets/Plugins/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/RecordStream.cs:264
    at Org.BouncyCastle.Crypto.Tls.TlsProtocol.SafeWriteRecord (Byte type, System.Byte[] buf, Int32 offset, Int32 len) [0x00000] in /Users/jnis/Documents/code/work/helsinki-airport-unity/Assets/Plugins/Best HTTP (Pro)/BestHTTP/SecureProtocol/crypto/tls/TlsProtocol.cs:528
    UniRx.Stubs.<Throw>m__A8 (System.Exception ex) (at Assets/Plugins/UniRx/Scripts/Observer.cs:270)
    UniRx.Observer+Subscribe`1[PSCOrder[]].OnError (System.Exception error) (at Assets/Plugins/UniRx/Scripts/Observer.cs:142)
    UniRx.Operators.DoOnErrorObservable`1+DoOnError[PSCOrder[]].OnError (System.Exception error) (at Assets/Plugins/UniRx/Scripts/Operators/Do.cs:222)
    UniRx.Operators.DoOnSubscribeObservable`1+DoOnSubscribe[PSCOrder[]].OnError (System.Exception error) (at Assets/Plugins/UniRx/Scripts/Operators/Do.cs:410)
    UniRx.Operators.AsObservableObservable`1+AsObservable[PSCOrder[]].OnError (System.Exception error) (at Assets/Plugins/UniRx/Scripts/Operators/AsObservable.cs:34)
    UniRx.Subject`1[PSCOrder[]].OnError (System.Exception error) (at Assets/Plugins/UniRx/Scripts/Subjects/Subject.cs:57)
    PaymentServiceCoreAPI+<AuthenticatedRequest>c__AnonStorey3F`2[PSCOrder[],System.Object].<>m__B3 (System.Exception ex) (at Assets/Scripts/APIs/PaymentServiceCore/PaymentServiceCoreAPI.cs:133)
    UniRx.Operators.DoOnErrorObservable`1+DoOnError[PSCOrder[]].OnError (System.Exception error) (at Assets/Plugins/UniRx/Scripts/Operators/Do.cs:212)
    UnityEngine.Debug:LogException(Exception)
    UniRx.MainThreadDispatcher:<unhandledExceptionCallback>m__E0(Exception) (at Assets/Plugins/UniRx/Scripts/UnityEngineBridge/MainThreadDispatcher.cs:350)
    UniRx.InternalUtil.ThreadSafeQueueWorker:ExecuteAll(Action`1) (at Assets/Plugins/UniRx/Scripts/InternalUtil/ThreadSafeQueueWorker.cs:85)
    UniRx.MainThreadDispatcher:Update() (at Assets/Plugins/UniRx/Scripts/UnityEngineBridge/MainThreadDispatcher.cs:545)
     
  2. marteus

    marteus

    Joined:
    Jul 17, 2015
    Posts:
    4
    @BestHTTP
    I unfortunately need the alternate SSL as the default mono implementation does not work for our Amazon S3 + CloudFront https urls.

    Using the precompiled dlls improved the situtation a bit (~5MB vs ~6MB and ~4min vs ~5min)
     
  3. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @jhnissin

    I wouldn't think so. The previous one looks like some protocol error, while this one might be a network error. Can you try out without certification validation?

    Another one that might worth to check is to disable Server Name Indication by commenting out or deleting the
    Code (CSharp):
    1. hostNames.Add(CurrentRequest.CurrentUri.Host);
    in the HTTPConnection.cs around line 614.
     
  4. jhnissin

    jhnissin

    Joined:
    Sep 7, 2015
    Posts:
    27
    @BestHTTP

    I tried setting the UseAlternateSSL for all requests as false, however, the problem still persists -.-". I have contacted the admin of the load balancer/firewall however I am not sure what to ask him to look for.
     
  5. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @jhnissin

    How easy to reproduce these errors on your end?
    You already sent me endpoints to the server, but it's possible that you can send me a small repro-project too using these uris?
    Yesterday I made a little test by sending a request every second to one of the end point. I had let it run maybe half an hour without any error.
     
  6. jhnissin

    jhnissin

    Joined:
    Sep 7, 2015
    Posts:
    27
    @BestHTTP

    These erros come fairly often, however, separating all the server communication from the other application logic might be a bit tall order. I'll try if I can build a test scene. Since you can't reproduce these errors it sounds like something is wrong on our end.
     
  7. jhnissin

    jhnissin

    Joined:
    Sep 7, 2015
    Posts:
    27
    @BestHTTP

    I managed to bump up the number of issues by creating requests to the end points every two seconds and setting the HTTPManager settings as follows:

    BestHTTP.HTTPManager.KeepAliveDefaultValue = false;
    BestHTTP.HTTPManager.MaxConnectionIdleTime = System.TimeSpan.FromSeconds (1f);

    I also managed to log the following information about the TlsProtocol from the ProcessAlert function:

    TlsProtocol LogSession: Level: 2, description: 47. Session parameters: Cipher suite: unavailable, compression algorithm: unavailable. Resumable: False, resumed: False. Connection state: 13

    Furthermore, previously while logging I detected a lot of write errors at the same connection state. I am still wondering whether these might be connected.
     
    Last edited: Sep 23, 2016
  8. jhnissin

    jhnissin

    Joined:
    Sep 7, 2015
    Posts:
    27
    @BestHTTP

    Sorry for the spam, but I am explaining this as I debug. It seems the errors only happen when UseAlternateSSL is true. However, we really need to be able to validate the server side certificates so we need to be able to set the CertificateVerifier. The errors start happening even if I don't set the CustomCertificateVerifyer for the HTTP requests and they also happen even if I set the certificate verifier and just make it return true for every IsValid request.
     
  9. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @jhnissin

    Referring to the RFC, level 2 description 47 is an un-resumable error, and the error itself is illegal_parameter. (You already got these.) The description for illegal_parameter is the following:
    This why I thought it would be good to try disabling SNI, because I added it myself, it wasn't in the lib by default. (The support was there, ofc, but had to add additional code to be able to send it.)

    You wrote another error too, it was a decryption_failed:
    I don't know how it can be that sometime it works, and sometime don't...

    Write errors: maybe the server detects other fatal errors in other parts and just closes the connection.
     
  10. SubZeroGaming

    SubZeroGaming

    Joined:
    Mar 4, 2013
    Posts:
    1,008
    Hello,

    I'm working on an application that integrates your plugin, and everything works spectacular. However, on a poor connection, when fetching facebook friends, the app will freeze.

    I'm having a little trouble figuring out what the issue is. Would you mind taking a look at the Crash logs?

    I contacted Prime31 (We're using their facebook integration) and they assured me it's not them as all their calls came back success over 200.

    I believe it's something todo with possibly the Dispose method, but i'm not entirely sure.

    Any guidance would be great.

    Thank you!

    Link to crash log: http://pastebin.com/Ckdg0XJd
     
  11. aanfuso

    aanfuso

    Joined:
    Jun 25, 2014
    Posts:
    1
    Hey guys! I was wondering, what is the difference between Pro and Basic Edition?
     
  12. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @SubZeroGaming

    Unfortunately I see no useful information in the linked log.
    Increasing the plugin's log level may help to get some clue what's happening:
    Code (CSharp):
    1. BestHTTP.HTTPManager.Logger.Level = BestHTTP.Logger.Loglevels.Information;
     
  13. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @aanfuso

    The main difference is, that my Pro version contains all source code and because of this it can support some additional features:
    1.) You can disable different features to reduce build size.
    2.) You can access some internal functions and properties that can come handy sometime.
    3.) I can send bugfixes more quickly as I can send only the files that changed.
    4.) The Pro version also contains precompiled dlls that you would receive with the Basic, so you can decide what you want to use. Using the dlls can reduce build times.
     
  14. jhnissin

    jhnissin

    Joined:
    Sep 7, 2015
    Posts:
    27
    @BestHTTP

    I know this is a longshot, but would there be anyway to make the SSL stream in the HTTPConnection class (around line 627) actually invoke the callback that you guys have set? Currently It seems that Mono is never invoking that RemoteCertificationValidationCallback and it's actually documented if you go to the function definition:

    [MonoTODO ("userCertificateValidationCallbackisnotpassedX509ChainandSslPolicyErrorscorrectly")]

    I'd preferably need to come up with a workaround for this, since fixing the validation issues of the BouncyCastle library might be a bit tall order with the current time frame that I am working with.
     
  15. jhnissin

    jhnissin

    Joined:
    Sep 7, 2015
    Posts:
    27
    Nevermind, I just realized CustomCertificateValidator is different from CustomCertificateVerifier (silly me).
     
  16. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @jhnissin

    I found the mono implementation unreliable, hence why I usually don't recommend it.
     
  17. jhnissin

    jhnissin

    Joined:
    Sep 7, 2015
    Posts:
    27
    @BestHTTP

    Yeah it seems that way, I am not getting the complete certificate chain via that callback. I am running out of ideas here how to get both reliable TLS and server side certificate validation working.
     
  18. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @jhnissin

    I have choosed BouncyOrg to have a pure c# solution and spare a lot of headaches to myself, but compiling and using a native plugin instead can work too.
    I heard a lot of good about mbed TLS.

    Another option would be to create a new connection class derived from the ConnectionBase that would use native to the platform functions to implement request-response processing where certificate validation might be better.
    I used this approach for WebGL builds, where the whole request-response turn done by the browser.
     
  19. AliAfshari

    AliAfshari

    Joined:
    Sep 12, 2014
    Posts:
    13
    Hi
    I am working with besthttp pro version 1.9.9. When I send a get request to any domain more than 90 percent times don't get any response. callback method executes but with empty DataAsText But WWW works fine at the same situation. It works fine on android but on pc (windows 7 & 10) there is this problem. I tested many things but can't solve the problem. but when I change my internet connection the problem on pc solved. I use besthttp for SignalR and it causes signalr can't connect to server at 90 percent times.
    I disable firewall too but nothing changed. when signalr server is on the same pc there is no problem.
     
  20. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @AliAfshari

    Well, first I would recommend to upgrade to the latest version from the Asset Store. v1.9.9 released more than 7 months ago.

    Then, you can check the request's state for more details what went wrong. Something like this:
    Code (CSharp):
    1. Uri uri = new Uri("http://httpbin.org/get");
    2.  
    3. HTTPRequest request = new HTTPRequest(uri, (req, resp) =>
    4. {
    5.     switch (req.State)
    6.     {
    7.         // The request finished without any problem.
    8.         case HTTPRequestStates.Finished:
    9.             if (resp.IsSuccess)
    10.             {
    11.                 Debug.Log("Request Finished Successfully! Response: " + resp.DataAsText);
    12.  
    13.                 // TODO: Request finished. Process server sent data.
    14.             }
    15.             else // Internal server error?
    16.                 Debug.LogWarning(string.Format("Request Finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}",
    17.                                                 resp.StatusCode,
    18.                                                 resp.Message,
    19.                                                 resp.DataAsText));
    20.             break;
    21.  
    22.         // The request finished with an unexpected error. The request's Exception property may contain more info about the error.
    23.         case HTTPRequestStates.Error:
    24.             Debug.LogWarning("Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception"));
    25.             break;
    26.  
    27.         // The request aborted, initiated by the user.
    28.         case HTTPRequestStates.Aborted:
    29.             Debug.LogWarning("Request Aborted!");
    30.             break;
    31.  
    32.         // Connecting to the server is timed out.
    33.         case HTTPRequestStates.ConnectionTimedOut:
    34.             Debug.LogError("Connection Timed Out!");
    35.             break;
    36.  
    37.         // The request didn't finished in the given time.
    38.         case HTTPRequestStates.TimedOut:
    39.             Debug.LogError("Processing the request Timed Out!");
    40.             break;
    41.     }
    42. });
    43.  
    44. request.Send();
    You can also increase logging detail:
    Code (CSharp):
    1. BestHTTP.HTTPManager.Logger.Level = BestHTTP.Logger.Loglevels.All;

    After these we will know more about what went wrong.
     
  21. benacler

    benacler

    Joined:
    Oct 26, 2013
    Posts:
    6
    Hi there,

    Updated to the latest version, but web player support is somewhat broken.
    Using Unity 5.3.6f1 as soon as I make a post request , I get back Internal TLS error, this could be an attack! Other platform works like a charm...
    Any hint ?
     
  22. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @benacler

    Can you try out by setting the alternate ssl to false?
    You can disable it globally by setting the BestHTTP.UseAlternateSSLDefaultValue to false.
     
  23. AliAfshari

    AliAfshari

    Joined:
    Sep 12, 2014
    Posts:
    13
    Hi
    I got version 1.9.14 but the problem is existed. I tested many links and found that the problem is only for signalr links. http get works fine with all links of my servers but with /signalr and /signalr/hubs doesn't work.
     
  24. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @AliAfshari

    Can you send the logs that you receive after you set the loglevel to All? It would be very helpful, as it can be a server misconfiguration, a bug in the plugin, etc.
    Also, how is my SignalR samples are work, are they produce errors too?
     
  25. dndr

    dndr

    Joined:
    Jun 4, 2014
    Posts:
    2
    I saw that the websocket library doesn't immediately throw an error when sending a message to a socket that's already closed. Is it possible to check the 'readyState' of the ws just before sending a message (just like in the HTML5 API?)
     
  26. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @dndr

    It can be switched on with some TCP parameters, however I wasn't found a reliably common parameter that would work.
    You can turn on and experiment with the parameters in the \Assets\Best HTTP (Pro)\BestHTTP\PlatformSupport\TcpClient\TcpClient.cs around lines 467-468 and 480.
     
  27. Ben-BearFish

    Ben-BearFish

    Joined:
    Sep 6, 2011
    Posts:
    1,204
    @BestHTTP We're noticing a weird issue, which we've only tested in the editor (haven't made a build yet), where when we are finished and exit play mode the editor freezes up for a few seconds. We've noticed it happens while a http call is in progress. Do we need to call something to cleanup the requests on exit?
     
  28. AliAfshari

    AliAfshari

    Joined:
    Sep 12, 2014
    Posts:
    13
    @BestHTTP
    When I set loglevel to all the problem disappear and when set to Error problem appears. I commented all log code line by line and test play unity to find which log code solve the problem. I found when in "Receive" method in "HTTPResponse.cs"
    add a code to sleep the request thread for about 100 ms problem solved and that log codes generate a few delay that cause problem disappear. I think code in line 196 need more time to execute.

     
  29. gabebond

    gabebond

    Joined:
    Jul 28, 2013
    Posts:
    3
    There seems to be a bug in binary upload for Socket.io when the binary size is greater than maxFragmentSize.

    WebSocketFrame.cs line 144:
    int count = (this.Data.Length / maxFragmentSize) + (this.Data.Length % maxFragmentSize) - 1;
    It should be:
    int count = (this.Data.Length / maxFragmentSize) + (this.Data.Length % maxFragmentSize == 0 ? -1 : 0);

    Please let me know when the fix is released
     
  30. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @Ben-BearFish

    Tried to reproduce this without any luck. I tried with my large file download sample and with the SignalR demo hub too (using the polling transport).
    Can you share more details about it?
     
  31. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @AliAfshari

    If you are using the latest version of the plugin, can you try this by un-comment the lines 497-498 in the HTTPConnection.cs in the \Assets\Best HTTP (Pro)\BestHTTP\ folder? So it should look like this:
    Code (CSharp):
    1.  
    2. Stream = Client.GetStream();
    3. if (Stream.CanTimeout)
    4.   Stream.ReadTimeout = Stream.WriteTimeout = (int)CurrentRequest.Timeout.TotalMilliseconds;
    5.  
    6. #if !BESTHTTP_DISABLE_PROXY
    7.  
     
  32. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @gabebond

    You are totally right! I think next week will i will upload a new release.
     
  33. AliAfshari

    AliAfshari

    Joined:
    Sep 12, 2014
    Posts:
    13
    I un-commented the lines but nothing changed. When I connect to my signalr server through a vpn on another country there is no problem. I think vpn causes some delay and it works like sleep the thread
     
  34. gabebond

    gabebond

    Joined:
    Jul 28, 2013
    Posts:
    3
    @BestHTTP

    Thanks for the fast response. I look forward to the new release
     
  35. geff

    geff

    Joined:
    Mar 3, 2013
    Posts:
    28
    Hi @BestHTTP,

    my company use your plugin (Pro version) for REST API requests.
    Works fine :)

    I'm writing some Unit Test code to check if all works good.
    I'm using ManualResetEvent for thread synchronization but unfortunatly I receive the response after the WaitOne TimeOut.

    Do you have any ideas that allows me to write AUT?

    Code (csharp):
    1.  
    2.     [Test]
    3.     public void Connect2()
    4.     {
    5.         _manualEvent = new ManualResetEvent(false);
    6.         bool success = false;
    7.  
    8.         BestHTTP.HTTPRequest request = new BestHTTP.HTTPRequest(uri, HTTPMethods.Post,
    9.                (req, resp) =>
    10.                {
    11.                    success = true;
    12.                    _manualEvent.Set();
    13.                });
    14.  
    15.         request.Send();
    16.  
    17.         bool timeOut = !_manualEvent.WaitOne(5000, false);
    18.  
    19.         if (timeOut)
    20.             throw new System.Exception("Time out");
    21.         else
    22.             Assert.IsTrue(success);
    23. }
    24.  
     
  36. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @geff

    While the request-response pair is sent/read on a thread, callbacks are dispatched from a Unity Update function. So, the WaitOne will block so that the callback can't be fired.

    A while ago wrote a little helper class that can be used to send a request and block until its result:
    Code (CSharp):
    1. /// <summary>
    2. /// Helper class to be able send a blocking HTTPRequest
    3. /// </summary>
    4. public sealed class BlockingRequestHelper
    5. {
    6.     #region Private Fields
    7.  
    8.     /// <summary>
    9.     /// AutResetEvent to wait for the request
    10.     /// </summary>
    11.     AutoResetEvent mre = new AutoResetEvent(false);
    12.  
    13.     /// <summary>
    14.     /// AutResetEvent to pause the thread
    15.     /// </summary>
    16.     AutoResetEvent threadPing = new AutoResetEvent(false);
    17.  
    18.     /// <summary>
    19.     /// Thread to call HTTPManager.OnUpdate
    20.     /// </summary>
    21.     Thread thread;
    22.  
    23.     /// <summary>
    24.     /// While true, HTTPManager.OnUpdate will be called
    25.     /// </summary>
    26.     bool doUpdate;
    27.  
    28.     /// <summary>
    29.     /// While true, the thread will not quit
    30.     /// </summary>
    31.     bool threadAlive;
    32.  
    33.     /// <summary>
    34.     /// To save the originally set callback
    35.     /// </summary>
    36.     OnRequestFinishedDelegate originalCallback;
    37.  
    38.     #endregion
    39.  
    40.     #region Public Functions
    41.  
    42.     /// <summary>
    43.     /// This will send the request and will block until it's finished
    44.     /// </summary>
    45.     public bool SendAndWait(HTTPRequest request, TimeSpan timeout)
    46.     {
    47.         HTTPManager.Logger.Information("BlockingRequest", "Sending Request...");
    48.  
    49.         // This must be called on Unity's main thread
    50.         HTTPManager.Setup();
    51.  
    52.         // Save the callback
    53.         originalCallback = request.Callback;
    54.  
    55.         // Set a new callback, where we will ping the ManualResetEvent
    56.         request.Callback = (req, resp) => mre.Set();
    57.  
    58.         // Send the request
    59.         request.Send();
    60.  
    61.         // Start or resume our thread to do OnUpdates
    62.         StartThread();
    63.  
    64.         // Block until the request's hijacked callback is called and will set the ManualResetEvent
    65.         bool result = mre.WaitOne(timeout);
    66.  
    67.         // Pause the thread
    68.         PauseThread();
    69.  
    70.         // Call the originally set callback on the main thread
    71.         if (originalCallback != null)
    72.         {
    73.             try
    74.             {
    75.                 originalCallback(request, request.Response);
    76.             }
    77.             catch(Exception ex)
    78.             {
    79.                 HTTPManager.Logger.Exception("BlockingRequest", "calling originalCallback", ex);
    80.             }
    81.         }
    82.  
    83.         HTTPManager.Logger.Information("BlockingRequest", "Request Done!");
    84.  
    85.         return result;
    86.     }
    87.  
    88.     /// <summary>
    89.     /// This will stop the started thread. Call it when no more SendAndWait will be called
    90.     /// </summary>
    91.     public void StopThread()
    92.     {
    93.         if (thread != null)
    94.         {
    95.             HTTPManager.Logger.Information("BlockingRequest", "Stopping Thread");
    96.  
    97.             thread = null;
    98.             doUpdate = false;
    99.             threadAlive = false;
    100.             threadPing.Set();
    101.         }
    102.     }
    103.  
    104.     #endregion
    105.  
    106.     #region Private Helper Functions
    107.  
    108.     void StartThread()
    109.     {
    110.         // Start a thread
    111.         if (thread == null)
    112.         {
    113.             HTTPManager.Logger.Information("BlockingRequest", "Starting new Thread");
    114.  
    115.             thread = new Thread(new ThreadStart(ThreadFunc));
    116.             doUpdate = true;
    117.             threadAlive = true;
    118.             thread.Start();
    119.         }
    120.         else
    121.         {
    122.             // Resume updating
    123.             HTTPManager.Logger.Information("BlockingRequest", "Resuming Thread");
    124.  
    125.             doUpdate = true;
    126.             threadPing.Set();
    127.         }
    128.     }
    129.  
    130.     void PauseThread()
    131.     {
    132.         doUpdate = false;
    133.     }
    134.  
    135.     void ThreadFunc()
    136.     {
    137.         HTTPManager.Logger.Information("BlockingRequest", "Thread Started");
    138.  
    139.         while (threadAlive)
    140.         {
    141.             while (doUpdate)
    142.             {
    143.                 // Don't eat all cpu cycles
    144.                 Thread.Sleep(100);
    145.  
    146.                 HTTPManager.OnUpdate();
    147.             }
    148.  
    149.             HTTPManager.Logger.Information("BlockingRequest", "Thread Paused");
    150.  
    151.             threadPing.WaitOne();
    152.  
    153.             HTTPManager.Logger.Information("BlockingRequest", "Thread Resumed");
    154.         }
    155.  
    156.         HTTPManager.Logger.Information("BlockingRequest", "Thread Quit");
    157.     }
    158.  
    159.     #endregion
    160. }
    Using this class, you can write a test like this:
    Code (CSharp):
    1. using System;
    2.  
    3. using BestHTTP;
    4. using NUnit.Framework;
    5.  
    6. namespace BestHTTP_Tests
    7. {
    8.     [TestFixture]
    9.     [Category("Basic Tests")]
    10.     public sealed class BestHTTPUnityTests
    11.     {
    12.         BlockingRequestHelper helper;
    13.         TimeSpan generalTimeout = TimeSpan.FromSeconds(5);
    14.  
    15.         [TestFixtureSetUp]
    16.         public void SetUp()
    17.         {
    18.             if (helper == null)
    19.                 helper = new BlockingRequestHelper();
    20.         }
    21.  
    22.         [TestFixtureTearDown]
    23.         public void TearDown()
    24.         {
    25.             if (helper != null)
    26.             {
    27.                 helper.StopThread();
    28.                 helper = null;
    29.             }
    30.         }
    31.  
    32.         [Test]
    33.         public void PostTest()
    34.         {
    35.             bool success = false;
    36.  
    37.             HTTPRequest request = new HTTPRequest(new Uri("http://httpbin.org/post"),
    38.                                                   HTTPMethods.Post,
    39.                                                   (req, resp) => success = resp.IsSuccess);
    40.  
    41.             request.AddField("Field 1", "Value1");
    42.             request.AddField("Field 2", "Value2");
    43.  
    44.             bool timeOut = !helper.SendAndWait(request, generalTimeout);
    45.  
    46.             if (timeOut)
    47.                 throw new System.Exception("Time out");
    48.             else
    49.                 Assert.IsTrue(success);
    50.         }
    51.  
    52.         [Test]
    53.         public void GetTest()
    54.         {
    55.             bool success = false;
    56.  
    57.             HTTPRequest request = new HTTPRequest(new Uri("http://httpbin.org/get"),
    58.                                                   HTTPMethods.Get,
    59.                                                   (req, resp) => success = resp.IsSuccess );
    60.  
    61.             bool timeOut = !helper.SendAndWait(request, generalTimeout);
    62.  
    63.             if (timeOut)
    64.                 throw new System.Exception("Time out");
    65.             else
    66.                 Assert.IsTrue(success);
    67.         }
    68.     }
    69. }
    SetUp() and TearDown() will be called once, when all test are run (if you run multiple ones).

    Let me know how it works.
     
  37. AliAfshari

    AliAfshari

    Joined:
    Sep 12, 2014
    Posts:
    13
    I have this code on client
    Code (CSharp):
    1. SignalRCon[HubNames.MatchMakeHub].Call(HubMethodsName.MatchMake, (Hub hub, ClientMessage originalMessage, ResultMessage result) => responseCallBack((MatchData)result.ReturnValue));
    and a method with this header on server
    Code (CSharp):
    1. public async Task<MatchData> MatchMake()
    How can I Convert "result.ReturnValue" on client to "MatchData" class?
     
    Last edited: Oct 9, 2016
  38. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @AliAfshari

    Unfortunately, no. The official implementation does the same thing.
     
  39. AliAfshari

    AliAfshari

    Joined:
    Sep 12, 2014
    Posts:
    13
    When I see result.ReturnValue it converted int values to float and add ".0" at end of them. so I replaced Json.Decode method with "Newtonsoft.Json.JsonConvert.DeserializeObject<IDictionary<string, object>>(json)" in DefaultJsonEncoder.cs class. problem solved. can it cause any problems later?

     
    Dustin-Horne likes this.
  40. AliAfshari

    AliAfshari

    Joined:
    Sep 12, 2014
    Posts:
    13
    Thank you best http for your answers and the awesome package. this package causes I can use signalr on server which is great for me.
    I have another question. I see http request are sent one after another. are signalr requests sent like https one by one Or sent simultaneous. are there any settings to change this behaviour?
     
  41. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @AliAfshari

    There is a JsonDotnetEncoder already in the \Assets\Best HTTP (Pro)\Examples\SignalR\Json Encoders\ folder. But just have to add the BESTHTTP_SIGNALR_WITH_JSONDOTNET symbol to the 'Scripting Define Symbols' under PlayerSettings/Other Settings. Doing so will change it to the default encoder too.
     
  42. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @AliAfshari

    Requests are sent out simultaneously, but the HTTPManager.MaxConnectionPerServer property controls how much connections will the plugin use to serve the requests. Its default value is 4, so in one time it can send out 4 requests.
     
  43. geff

    geff

    Joined:
    Mar 3, 2013
    Posts:
    28
    Thank you, it works, but not always with my implementation.
    Not sure why.
     
  44. 00christian00

    00christian00

    Joined:
    Jul 22, 2012
    Posts:
    1,035
    Hi,
    I just bought Besthttp. One advice, you should make more clear what are the differences between pro and basic, took I had to check side by side the description and only noticed Unity 4 support in the pro, so I supposed it was something related to a feature present in Unity4 pro that is now available in Unity 5 personal, so I went for basic.
    Then I just realized this is without source...
     
  45. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @geff

    Are you still getting "time out" exceptions?
     
  46. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @00christian00

    Thank you for your suggestion, and you are right ofc, I will try to make the differences more obvious.
     
  47. 00christian00

    00christian00

    Joined:
    Jul 22, 2012
    Posts:
    1,035
    Hi, do you know if websockets will be affected by the new App Transport Security enforced by Apple for 2017 requiring connections to use TLS 1.2?
    From Apple:
    https://developer.apple.com/library...Keys.html#//apple_ref/doc/uid/TP40009251-SW57

    What does websocket uses on ios?
    I know your assets support encrypted websocket but I would like to avoid it for performance reasons if possible.
     
  48. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @00christian00

    WebSocket uses the very same security layer as HTTPS. Using the default settings, TLS1.2 and the other requirements shouldn't be a problem.
     
  49. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @00christian00

    Although, the plugin doesn't use ATS, or other native classes/functions.
     
  50. geff

    geff

    Joined:
    Mar 3, 2013
    Posts:
    28
    Error was because I was sending the request myself.
    Nor more errors now, thanks.