Search Unity

Best HTTP Released

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

  1. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @Shankar-Ganesh

    That xml would be used if you use the android platform provided HTTP client. The plugin uses plain TCP channels and the os doesn't know what kind of data is going through it.

    By setting the HTTPManager's Proxy, all communication from the plugin will go through that proxy. But, the plugin still uses multiple connections (tcp channels), so there's no relation between the proxy and connection count!
     
  2. akitsu

    akitsu

    Joined:
    Nov 26, 2013
    Posts:
    38
    @BestHTTP got everything working. Everything works fine now and was able rip off 60% old because of that. HUGE thanks again!
     
  3. Volpi91

    Volpi91

    Joined:
    Nov 5, 2017
    Posts:
    3
    I have final question, how you can get both compressed and uncompressed file size?
     
  4. BestHTTP

    BestHTTP

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

    If you are lucky, the server sends the content with a Content-Length header so you can know the compressed length. The uncompressed size is what you have access to in the HTTPResponse object:

    Code (CSharp):
    1. private void OnRequestFinished(HTTPRequest req, HTTPResponse resp)
    2. {
    3.     switch (req.State)
    4.     {
    5.         // The request finished without any problem.
    6.         case HTTPRequestStates.Finished:
    7.             if (resp.IsSuccess)
    8.             {
    9.                 print("Uncompressed length: " + resp.Data.Length);
    10.                 print("Compressed length: " + resp.GetFirstHeaderValue("content-length"));
    11.                 Debug.Log("Uncompressed response: " + resp.DataAsText);
    12.             }
    13.             else
    14.             {
    15.                 Debug.LogWarning(string.Format("Request finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}",
    16.                                                 resp.StatusCode,
    17.                                                 resp.Message,
    18.                                                 resp.DataAsText));
    19.             }
    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.LogError("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. }
     
  5. akitsu

    akitsu

    Joined:
    Nov 26, 2013
    Posts:
    38
    yeah got lucky server sented right information, how I get that data streaming, not as single value, like bytesdownloaded += resp.GetFirstHeaderValue("content-length"));
     
  6. BestHTTP

    BestHTTP

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

    I'm sorry but i don't get it.
     
  7. Volpi91

    Volpi91

    Joined:
    Nov 5, 2017
    Posts:
    3
    OnRequestFinished you get as single value how big compressed file was. So I want percentage how much has been downloaded of compressed file
     
  8. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
  9. akitsu

    akitsu

    Joined:
    Nov 26, 2013
    Posts:
    38
    but thats also returns decompressed amount of downloaded
     
  10. BestHTTP

    BestHTTP

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

    No.
    Download progress always reports the raw downloaded bytes, and if possible the length of the content the server sends (raw, compressed bytes from the content-length header). Progress report happens first, then decompression and the decompressed data is sent to the streaming handler or buffered if no streaming.
     
  11. akitsu

    akitsu

    Joined:
    Nov 26, 2013
    Posts:
    38
    Thanks was again fix the problem!
     
  12. unity3_unity131

    unity3_unity131

    Joined:
    Dec 9, 2019
    Posts:
    2
    Hello,
    i have one question how many time socket connect and disconnect. i'm currently working socket event. i have face a problem socket connect minimum 4 time. than after not connecting socket
     
  13. BestHTTP

    BestHTTP

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

    There's a ReconnectionAttempts field in the SocketOptions class that you can set:
    Code (CSharp):
    1. SocketOptions options = new SocketOptions();
    2. options.ReconnectionAttempts = 10;
    3.  
    4. Manager = new SocketManager(new Uri(address), options);
     
  14. craigmann

    craigmann

    Joined:
    Sep 29, 2016
    Posts:
    15
    first pass on REST POST here...


    Code (CSharp):
    1. using System;
    2. using System.Text;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. using UnityEngine;
    6. using UnityEngine.UI;
    7. using UnityEngine.Events;
    8. using UnityEngine.Networking;
    9. using BestHTTP;
    10.  
    11. public class Main : MonoBehaviour
    12. {
    13.   public static Main Instance;
    14.  
    15.   private string jsonString;
    16.  
    17.   void Start()
    18.   {
    19.     Instance = this;
    20.   }
    21.  
    22.   private void OnRequestFinished(HTTPRequest req, HTTPResponse resp)
    23.   {
    24.     Debug.Log(resp.DataAsText);
    25.   }
    26.  
    27.   public void HandleLogin(string URL, string KEY, string SECRET)
    28.   {
    29.     jsonString = "{ \"key\": \"" + KEY + "\", \"secret\": \"" + SECRET + "\" }";
    30.    
    31.     var request = new HTTPRequest(new Uri(URL), HTTPMethods.Post, OnRequestFinished);
    32.     request.SetHeader("Content-Type", "application/json; charset=UTF-8");
    33.     request.RawData = Encoding.UTF8.GetBytes(jsonString);
    34.     request.Send();
    35.   }
    36. }
    37.  
    38.  
    besides the 500 from my service, I see the following in Unity console..

    [637220282209932120] Err [VariableSizedBufferPool]: Buffer already added to the pool!
    UnityEngine.Debug:LogError(Object)
    BestHTTP.Logger.DefaultLogger:Error(String, String) (at Assets/Best HTTP/Source/Logger/DefaultLogger.cs:76)
    BestHTTP.PlatformSupport.Memory.BufferPool:AddFreeBuffer(Byte[]) (at Assets/Best HTTP/Source/PlatformSupport/Memory/BufferPool.cs:491)
    BestHTTP.PlatformSupport.Memory.BufferPool:Release(Byte[]) (at Assets/Best HTTP/Source/PlatformSupport/Memory/BufferPool.cs:281)
    BestHTTP.Extensions.BufferPoolMemoryStream:Dispose(Boolean) (at Assets/Best HTTP/Source/Extensions/BufferPoolMemoryStream.cs:244)
    System.IO.Stream:Dispose()
    BestHTTP.HTTPRequest:SendOutTo(Stream) (at Assets/Best HTTP/Source/HTTPRequest.cs:1333)
    BestHTTP.Connections.HTTP1Handler:RunHandler() (at Assets/Best HTTP/Source/Connections/HTTP1Handler.cs:50)
    BestHTTP.Connections.HTTPConnection:ThreadFunc() (at Assets/Best HTTP/Source/Connections/HTTPConnection.cs:118)
    BestHTTP.PlatformSupport.Threading.<>c__DisplayClass4_0:<RunLongLiving>b__0() (at Assets/Best HTTP/Source/PlatformSupport/Threading/ThreadedRunner.cs:79)
    System.Threading.ThreadHelper:ThreadStart(Object)

    thoughts?
     
  15. BestHTTP

    BestHTTP

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

    What version of the plugin are you using?
     
  16. craigmann

    craigmann

    Joined:
    Sep 29, 2016
    Posts:
    15
    BestHTTP/2 Version: 2.0.5
    Unity Version: 2019.3.3f1
     
  17. BestHTTP

    BestHTTP

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

    Hmm, that quite strange. Could you send a repro-project to me?
     
  18. craigmann

    craigmann

    Joined:
    Sep 29, 2016
    Posts:
    15
    sent a pm to share
     
  19. hung-vt

    hung-vt

    Joined:
    Jul 26, 2017
    Posts:
    2
    Hi! I got 'failed: Error in connection establishment: net::ERR_CERT_COMMON_NAME_INVALID' error when I tried to connect to socket.io on my node.js server. You can visit my site: cotuongtv.vn to get more info. Please tell me how to fix this!
    ===========update==============
    I can connect to socket.io perfectly fine from android, ios or editor but webgl. I tried some setting in nginx but it did not work :(
     
  20. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
    @hung-vt

    Under WebGL the plugin must use the underlying browser's XmlHTTPRequest and Websocket implementation and they are very strict. I would suggest to open your browser's Developer tools and check its Console and Network tabs. They can be very helpful identifying errors. Then you can search for those errors.
     
  21. hung-vt

    hung-vt

    Joined:
    Jul 26, 2017
    Posts:
    2
    solved it! the problem is I did not connect to socket.io via domain name. I connect to my server by ip address. not sure how it works but it's fine for now. thanks
     
  22. RandAlThor

    RandAlThor

    Joined:
    Dec 2, 2007
    Posts:
    1,293
    I am interested to buy your asset but not sure for what i can use it.
    If i am making a game like clash of clan for example, for what can i use your asset to support this kind of game?
    Not that i want to make such a game but it is good for understanding for me.
    Can i connect from that kind of ios/android game to a server and check some values, save the new map that i placed my troops and buildings to the server, download a map from another user so that i can fight against his map and then save the results of the fight savely on the server again?
    Can i change values to the games from the server so that it uses the christmas theme or download the cristmas textures?
    Can i let the players chat together in the games based on guilds or locations?
    I know that i have to program the most things in the game myself but i am not sure if your asset is what i imagine. I just have some kind of feeling that it could help me in some areas to use a modern way and not have to use the old php scripts anymore. I am not a webprogrammer but willing to learn.
     
  23. BestHTTP

    BestHTTP

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

    The package implements multiple protocols that you can use for various goals:
    - You can use regular HTTP requests to check some values on a server, download or upload maps or other content, upload player moves and download opponent's.
    - A higher level protocol (Socket.IO, SignalR Core) with persistent connection to the server can be used for real-time chat, or other real-time uses (multiplayer for example).

    You still have to keep around your old php scripts, as the plugin is a client side solution only.

    While you can do HTTP requests with Unity's own solutions, the plugin supports connection pooling, cookies, caching with transparent offline use of the cache (depending on the server sent headers), the new HTTP/2 protocol and a lot more. All higher level protocols are built on top of these!
     
    RandAlThor likes this.
  24. roointan

    roointan

    Joined:
    Jan 8, 2018
    Posts:
    78
    @BestHTTP
    Hello, couldn't understand from the docs, so I'm asking here.
    Are both OnError and OnErrorDesc called when an error happens? (WebSocket)
     
  25. BestHTTP

    BestHTTP

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

    That's a bug in the documentation that i just fixed (thanks for pointing it out!), with recent versions there's only one OnError callback.
     
    roointan likes this.
  26. roointan

    roointan

    Joined:
    Jan 8, 2018
    Posts:
    78
  27. BestHTTP

    BestHTTP

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

    I think you see the old version cached by your browser.
     
  28. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
  29. roointan

    roointan

    Joined:
    Jan 8, 2018
    Posts:
    78
  30. BestHTTP

    BestHTTP

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

    The only difference between them is how the error is passed to the callback. OnError receives it as an exception, while OnErrorDesc receives a string. Otherwise they are identical. OnError with an exception was a bad choose when i initially implemented Websocket and i fixed it in the new version(removed OnErrorDesc and OnError receives a string now).

    As they have the very same behavior you can use whatever you choose to, but i would recommend to use OnErrorDesc as it would make easier a future upgrade to the new version.
     
    roointan likes this.
  31. roointan

    roointan

    Joined:
    Jan 8, 2018
    Posts:
    78
    @BestHTTP
    The game team I'm working with wants me to recognise packet loss and warn the player about network issues.
    Not when I expect a response, but also when I should be receiving a response.
    I see the default value for ping frequency is 1000, so at most with a delay of 1 second I should be able to know I'm not receiving network messages.
    Is that correct?
    And how?
    And if not correct, how can I recognise packet loss and network issues?

    (I also tried taking a look at webSocket.Latency, but it's always 0. All the time.)
     
    Last edited: Apr 19, 2020
  32. BestHTTP

    BestHTTP

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

    I don't think you could detect packet losses just from latency fluctuation. Latency can grow for other reasons too (congestion is a very real one for example).

    Just tried out and it works as expected, however, you have to set StartPingThread to true, otherwise pings are not sent.

    What you can do is to use Latency as an indicator for network condition, but it's calculated when the plugin receives back a pong message from the server. So, while latency can show that's everyting is OK, in reality the tcp connection might be already broken. But the plugin also exposes LastMessageReceived and that's when the plugin could read the last server message. If ping frequency is set to a lower value and the time between now and LastMessageReceived starts growing that can show that something is going wrong.
     
    roointan likes this.
  33. roointan

    roointan

    Joined:
    Jan 8, 2018
    Posts:
    78
    I don't regularly send messages, but a message could be being sent to me.
    So I need to know the connection is healthy.
    Enabling the StartPingThread also can't work for me, because it throws error after 10 seconds and I'm not sending messages regularly.
    I just wanted to ping, and decide based on latency myself
    (The decision is not closing the connection, but displaying a blinking wifi on screen)

    I hope we can go further from here, but thanks for the help.
     
  34. BestHTTP

    BestHTTP

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

    I don't know what error you receive, but sending a ping would trigger a server message (pong) too and you could blink your wifi icon every time websocket's LastMessageReceived is different when you last blinked.
     
  35. roointan

    roointan

    Joined:
    Jan 8, 2018
    Posts:
    78
    This message:
    No message received in the given time! Closing WebSocket. LastMessage: ...

    But oh, I think I need to change CloseAfterNoMesssage too.

    Though, I still can't get a correct value for Latency. it's always 0. I'm testing in the Editor, could it be any different on actual device?
    And last time message received doesn't help me too. I wanted to know when was the last time a ping correctly received a pong.
     
    Last edited: Apr 19, 2020
  36. BestHTTP

    BestHTTP

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

    That error means that no message is received at all from the server in the given time (10 seconds by default). There should be no difference on a device.
     
  37. roointan

    roointan

    Joined:
    Jan 8, 2018
    Posts:
    78
    Ok we will accept it as is.
    I have another issue with websocket.
    On Android, when I switch network (like from wifi to 4G, or enable a VPN), the library correctly identifies loss of connectivity and throws an event.
    On iOS though, this does not happen. The websocket state remains open, but messages don't pass through. And no error or close event (and the game hangs in there).
    Any solution for this?
     
  38. thetomatodev

    thetomatodev

    Joined:
    Apr 20, 2020
    Posts:
    11
    I am trying to call my azure signalR functions using best https.
    This is a test app I have created
    Code (CSharp):
    1. using Microsoft.AspNetCore.Http;
    2. using Microsoft.Azure.WebJobs;
    3. using Microsoft.Azure.WebJobs.Extensions.Http;
    4. using Microsoft.Azure.WebJobs.Extensions.SignalRService;
    5.  
    6. namespace TestApp
    7. {
    8.     public static class TestFunc
    9.     {
    10.         [FunctionName("negotiate")]
    11.         public static SignalRConnectionInfo GetSignalRInfo(
    12.         [HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequest req,
    13.         [SignalRConnectionInfo(HubName = "chat")] SignalRConnectionInfo connectionInfo)
    14.         {
    15.             return connectionInfo;
    16.         }
    17.  
    18.         [FunctionName("TestFunc")]
    19.         public static string Test(
    20.           [HttpTrigger(AuthorizationLevel.Anonymous, "get","post")] object message,
    21.           [SignalR(HubName = "chat")] IAsyncCollector<SignalRMessage> signalRMessages)
    22.         {
    23.             return "okscene";
    24.         }
    25.  
    26.     }
    27. }
    28.  
    And this is how I am calling the above code
    Code (CSharp):
    1. public void testsignalr()
    2.         {
    3.             IProtocol protocol = null;
    4. #if BESTHTTP_SIGNALR_CORE_ENABLE_GAMEDEVWARE_MESSAGEPACK
    5.             protocol = new MessagePackProtocol();
    6. #else
    7.             protocol = new JsonProtocol(new LitJsonEncoder());
    8. #endif
    9.              connection = new HubConnection(new Uri(AZURE_TITLE_URL), protocol);
    10.             connection.AuthenticationProvider = new AzureSignalRServiceAuthenticator(connection);
    11.             connection.OnConnected += Hub_OnConnected;
    12.             connection.OnError += Hub_OnError;
    13.             connection.OnClosed += Hub_OnClosed;
    14.             connection.StartConnect();
    15.  
    16.         }
    17.  
    18.         private void Hub_OnConnected(HubConnection obj)
    19.         {
    20.    
    21.             connection.Send("TestFunc");
    22.  
    23.             connection.Invoke<string>("TestFunc")
    24.                 .OnSuccess(ret => OnSuccess())
    25.                 .OnError(error => OnFailure());
    26.  
    27.         }
    I get connected but "TestFunc" doesn't gets called. Am I doing something wrong here?
     
  39. alvinchung

    alvinchung

    Joined:
    Aug 20, 2018
    Posts:
    3
    @BestHTTP

    I found an issue here.

    The "Reset" method in "HTTPUpdateDelegator" will cause an error when sending requests in EditorMode testing.

    "Reset" is actually an EditorMode event name. Therefore, if
    go.AddComponent<HTTPUpdateDelegator>()
    is executed in EditorMode, Unity will randomly throw error like
    [Error] Failed to call static function Reset because an object was provided


    Renaming "Reset" to some other name like "ResetSetup" will fix the issue.
     
  40. BestHTTP

    BestHTTP

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

    Unfortunately, reporting when the TCP channel is broken is up to the underlying OS. The plugin would detect the error when it tries to send data, but if there’s no error the plugin just can’t know that there’s any problem with the connection.
     
    roointan likes this.
  41. BestHTTP

    BestHTTP

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

    As i see your TestFunc can be triggered through HTTP: HttpTrigger(AuthorizationLevel.Anonymous, "get","post")
     
  42. BestHTTP

    BestHTTP

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

    Reset is there to support Unity's experimental Enter Play Mode Settings. To this date didn't receive any issues about it, so i'm quite intersted when you receive this error and what version of Unity are you using.
     
  43. alvinchung

    alvinchung

    Joined:
    Aug 20, 2018
    Posts:
    3
    @BestHTTP

    The following is an example EditMode test with BestHttp/2
    Code (CSharp):
    1.         [UnityTest]
    2.         public IEnumerator TestSimpleHttp()
    3.         {
    4.             var req = new HTTPRequest(new Uri("https://www.google.com"));
    5.             req.Send();
    6.             yield return _EditorModeAdvance(req);
    7.         }
    8.      
    9.         public static IEnumerator _EditorModeAdvance(IEnumerator block)
    10.         {
    11.             while (block.MoveNext())
    12.             {
    13.                 HTTPManager.OnUpdate();
    14.                 yield return null;
    15.             }
    16.         }
    It failed when it is executed first time after opening the project.
    The error message is
    The root cause is that Unity considers Reset is a Unity Message but also declared as a static method.
    See https://docs.unity3d.com/ScriptReference/MonoBehaviour.Reset.html
    Note my Unity version is 2018.4.13f1.
     
  44. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,664
  45. wicea

    wicea

    Joined:
    Jan 23, 2016
    Posts:
    18
    @BestHTTP Hi!
    Could you please explain me about the implementation of timeout properties?

    I'm a bit confused with my results of tests.

    My tests.
    I tested networking in 100% packet loss mode (I'm using Network Link Conditioner for OS X, but I'm not sure that it's important).
    And discovered that first POST request always returns ConnectionTimeout error after ~20-25 seconds.
    I tried to set properties (differenet values - 2, 5, 10 seconds) globally in manager and locally for requests - nothing changed.

    Code (CSharp):
    1.  
    2. HTTPManager.ConnectTimeout = TimeSpan.FromSeconds(2);
    3. HTTPManager.RequestTimeout = TimeSpan.FromSeconds(2);
    4. ...
    5. httpRequest.MaxRetries = 0;
    6. httpRequest.ConnectTimeout = TimeSpan.FromSeconds(2);
    7. httpRequest.Timeout = TimeSpan.FromSeconds(2);
    8. httpRequest.Send();
    As a result any GET request will return callback after 2 seconds.
    But POST request returns callback after 20-25 seconds. If I retry POST it begins to return callback after 2 seconds as intended.

    Is it by design?
    I'm using v.2.0.5 from your last PM.
     
  46. BestHTTP

    BestHTTP

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

    In v2.0.6 there's a fix to make timeouts better, you should be able to upgrade without any issues. Also, if you could send logs, that would be helpful.
     
  47. wicea

    wicea

    Joined:
    Jan 23, 2016
    Posts:
    18
    Yeah, seems your fix is working. I'm receiving timeouts after 2 sec right now.
    Thanks!
     
  48. naqueve

    naqueve

    Joined:
    Sep 19, 2018
    Posts:
    2
    Page 59 by IVPathfinder

    I'm seeing this same issue ramdomly. The server's logger doesnt even log the request. The BestHTTP logger also says
    Status Line: ''


    Also I dont see this log before the "Status Line" one when it fails.
    [637232034159089506] I [ConnectionEventHelper]: Processing connection event: [ConnectionEventInfo SourceConnection: [-1006031360:http://localhost:3000], Event: ProtocolSupport, State: Initial, ProtocolSupport: HTTP1]


    I use the latest version (2.0.6) with
    Code (CSharp):
    1. request.DisableCache = true;
    2. request.MaxRetries = 0;
    (I tried without them and it still happens)

    Do you know how can i fix this issue?
     
    Last edited: Apr 24, 2020
  49. BestHTTP

    BestHTTP

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

    This error happens when the plugin wrote the request to the network and waiting for the response. But, instead of a valid response, the tcp channel got broken or closed and the plugin couldn't read anything.

    You can try disabling connection reuse:
    Code (CSharp):
    1. HTTPManager.KeepAliveDefaultValue = false;
    Or lower the connection idle time:
    Code (CSharp):
    1. HTTPManager.MaxConnectionIdleTime = TimeSpan.FromSeconds(10);
     
  50. naqueve

    naqueve

    Joined:
    Sep 19, 2018
    Posts:
    2
    Thank you for your explanation! I will try to fix it with that.
     
    Last edited: Apr 25, 2020