Search Unity

Best HTTP Released

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

  1. Jochanan

    Jochanan

    Joined:
    Nov 9, 2016
    Posts:
    70
    Hi, any idea what might have caused this one?
    Code (CSharp):
    1. NullReferenceException: Object reference not set to an instance of an object
    2. BestHTTP.HTTPConnection.ThreadFunc () (at Assets/Plugins/Best HTTP (Pro)/BestHTTP/HTTPConnection.cs:412)
    3. BestHTTP.PlatformSupport.Threading.ThreadedRunner+<>c__DisplayClass4_0.<RunLongLiving>b__0 () (at Assets/Plugins/Best HTTP (Pro)/BestHTTP/PlatformSupport/Threading/ThreadedRunner.cs:79)
    4. System.Threading.Tasks.Task.InnerInvoke () (at <7d97106330684add86d080ecf65bfe69>:0)
    5. System.Threading.Tasks.Task.Execute () (at <7d97106330684add86d080ecf65bfe69>:0)
    6.  
     
  2. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,351
    @Jochanan

    Don't know, is it a common exception?
     
  3. tylo

    tylo

    Joined:
    Dec 7, 2009
    Posts:
    130
  4. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,351
    @tylo

    Yes, it's coming in the next major update.
     
  5. tylo

    tylo

    Joined:
    Dec 7, 2009
    Posts:
    130
    Do you have a timeline on when that will be?
     
  6. Jochanan

    Jochanan

    Joined:
    Nov 9, 2016
    Posts:
    70
    Not at all, i have seen it for the first time
     
  7. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,351
    @tylo

    No, but I try to release it before the end of this year.
     
  8. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,351
    @Jochanan

    Seems to be a threading issue. I rewrote the threading code of the plugin for the next major version to avoid issues like this.
     
    Jochanan likes this.
  9. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    867
    Having same issue, @BestHTTP can you please add your in namsespace as GameSparks is no more in active development.
    and Gamesparks is also used dll so cant edit their side of code
     
    Last edited: Sep 7, 2019
  10. tylo

    tylo

    Joined:
    Dec 7, 2009
    Posts:
    130
    Are the files you cache raw files, or do they also contain extra bits of data that BestHTTP processes before getting to the true file?

    I wanted to try a test the speed of passing the path to a cached file for
    AssetBundle.LoadFromFileAsync
    instead of having BestHTTP open the cached file for me and pass an array of bytes/MemoryStream.

    Basically I am opening thousands of AssetBundles and was hoping to be able to commandeer your cache system, but I think I ran into a wall where your cached files are not the raw files themselves as I was hoping they were.

    EDIT: I was able to answer my own question. Yes, you do write HTTP headers to the Cache files.
     
    Last edited: Sep 8, 2019
  11. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,351
    @jGate99

    As it would be non backward compatible change it will be fixed only in the next major version.
     
    jGate99 likes this.
  12. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,351
    @tylo

    Yep, it stores additional information too. But, you might use something like this:
    Code (CSharp):
    1. System.Collections.IEnumerator LoadFromCache(Uri uri)
    2. {
    3.     var entity = BestHTTP.Caching.HTTPCacheService.GetEntity(uri);
    4.     if (entity != null && entity.IsExists())
    5.     {
    6.         int length;
    7.         using (var stream = entity.GetBodyStream(out length))
    8.         {
    9.             var async = UnityEngine.AssetBundle.LoadFromStreamAsync(stream);
    10.             yield return async;
    11.  
    12.             AssetBundle loadedAssetBundle = async.assetBundle;
    13.             // TODO: use loadedAssetBundle to load assets
    14.         }
    15.     }
    16. }
     
    tylo likes this.
  13. jGate99

    jGate99

    Joined:
    Oct 22, 2013
    Posts:
    867
    Any idea when next major version is expected?
     
  14. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,351
    @jGate99

    Not really. There are still a few important things on my todo list, but it should be out this year.
     
    jGate99 likes this.
  15. LR-Developer

    LR-Developer

    Joined:
    May 5, 2017
    Posts:
    70
    Hello,

    I have my Unity process hosted in a WPF app and try to use BestHTTP for (local) inter process communication of those both.

    First I tried to use Signalr Core, but I had heavy Problems getting the Signalr Core Server working in my WPF app, because this needs ASP it seems…

    So I switched over and used Named Pipes instead. The WPF is the Server, the Unity has the Client pipe. Works very well for Server is started, Client is started, connection is established. And Server sends Messages to Client, 100% successfull, direct Client answers also successful…
    Both are InOut pipes and asynchronous. It was very unstable before I set to asynchrnous, UI Always freezes after a while.

    But now it never freezes, Messages from Client to Server work perfect, but when the Client itself now sents a message, that is sent from a GameObjects Update void, it never reaches the Server. When Client sents an answer to the Servers message it arrives at the Server, if Client sents from an Update void, it never reaches the Server.

    Or is there a bettere way? I Need inter process communication from WCF app to (hosted) Unity app in both directions, sending strings and (files or Byte arrays or stream).

    Thanks a lot!
     
  16. Shaishav_yudiz

    Shaishav_yudiz

    Joined:
    May 8, 2018
    Posts:
    4
    @BestHTTP
    I'm using BestHttp pro for one of my games. I want to connect the root socket having different namespaces. For the security and validation, I am using tokens for each socket and namespace.
    I can connect the Root socket with the token and can able to fetch that token at the backend. But I can't able to add token in the namespace in the proper way to get it at the backend. Below is my code for the Root socket and the namespace connection. please guide me what is missing here.


    Code (CSharp):
    1. //Create socket options for the connection config.
    2.         SocketOptions options = new SocketOptions();
    3.         options.Reconnection = true;
    4.         options.ReconnectionAttempts = 3;
    5.         options.ReconnectionDelay = TimeSpan.FromSeconds(1);
    6.         options.Timeout = TimeSpan.FromSeconds(60);
    7.         options.AdditionalQueryParams = new            PlatformSupport.Collections.ObjectModel.ObservableDictionary<string, string>();
    8.         options.AdditionalQueryParams.Add("token", "token_123");
    9.         var manager = new SocketManager(new Uri("http://192.168.11.111:4001/socket.io/"), options);
    10.         //Root is connected
    11.         Socket root = manager.Socket;
    12.         //Connect the namespace with token
    13.         manager.Options.AdditionalQueryParams.Add("chat_token", "123456");
    14.         Socket chat = manager["/chat"];
    15.  
    Here the namespace connection is done but, I can't able to get the "chat_token" passed in it. What should be done at this?

    thanks in advance.
     
  17. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,351
    @LR-Developer

    I'm not sure i get what and how you did. If you send over your server and client i can take a look on it, but i think named pipes are quite unsupported by the plugin.

    WCF with http bindings could be used, but i'm sure that would be a lot of work as you have to send well formatted payload.

    SignalR Core can be self-hosted with the kestrel web server and should be able to run in a wpf app too.
     
    LR-Developer likes this.
  18. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,351
    @Shaishav_yudiz

    Additional query params might be used only once when connecting to the server, so even if you change it it will have no effect.

    Also, the "Root is connected" isn't accurate. When you access the root namespace, or any other one, it will just start to connect to that namespace, and that's a non-blocking operation!
     
  19. Shaishav_yudiz

    Shaishav_yudiz

    Joined:
    May 8, 2018
    Posts:
    4
    Hey @BestHTTP

    Thanks for the quick update on my query.
    I would like if you add this feature in next release. Eagery waiting for the update.:)
     
  20. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,351
  21. Prodigga

    Prodigga

    Joined:
    Apr 13, 2011
    Posts:
    777
    Hi there,

    We are trying to activate threaded update delegator. We set:
    Code (CSharp):
    1. BestHTTP.HTTPUpdateDelegator.IsThreaded = true;
    And I have ensured this happens prior to CheckInstance - I even put a log in there to make sure CheckInstance happens after IsThreaded = true. But when I enabled IsThreade, nothing happens.

    I am using socket manager (Socket IO), and my code looks like this:

    Code (CSharp):
    1. BestHTTP.HTTPUpdateDelegator.IsThreaded = true;
    2.         Debug.LogError("IsThreaded SET");
    3.  
    4.         _socketManager = new SocketManager(new Uri(url), new SocketOptions()
    5.         {
    6.             Reconnection = true,
    7.             Timeout = TimeSpan.FromSeconds(10),
    8.             ConnectWith = TransportTypes.WebSocket,
    9.             AutoConnect = false,
    10.         });
    11.         _socketManager.GetSocket().On(SocketIOEventTypes.Event, OnSocketMessage);
    12.         _socketManager.GetSocket().On(SocketIOEventTypes.Connect, OnSocketConnected);
    13.         _socketManager.GetSocket().On(SocketIOEventTypes.Disconnect, OnSocketDisconnected);
    14.         _socketManager.Open();
    This works perfectly without IsThreaded, but when I enable IsThreaded nothing happens. Maybe I am missing something? :)
     
  22. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,351
    @Prodigga

    You should check your console for error messages. There's a very few Unity classes and function you can use from a non unity main thread!
     
  23. Shaishav_yudiz

    Shaishav_yudiz

    Joined:
    May 8, 2018
    Posts:
    4

    Hi,
    I have created another authentication event from the root and authenticate the namespace from server end and it's working fine now.

    I have another query regarding the reconnection of the namespace.
    The root can reconnect after disconnection occurs from the server but the namespace can't.
    Is there any way to automatically reconnect the namespace if any disconnection occurs by the network?
    Can I set the separate SocketOptions for the namespace?

    thanks.
     
  24. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,351
    @Shaishav_yudiz

    Non-root namespaces will start (re)connect on first access. On a reconnected event you can call the manager's GetSocket function to initiate it.

    All namespaces share the same connection hence the same SocketOptions too.
     
  25. Shaishav_yudiz

    Shaishav_yudiz

    Joined:
    May 8, 2018
    Posts:
    4
  26. Prodigga

    Prodigga

    Joined:
    Apr 13, 2011
    Posts:
    777
    Hey there

    So it turns out I just had to make sure that IsThreaded was being set in
    Code (CSharp):
    1.     [RuntimeInitializeOnLoadMethod]
    2. #if UNITY_EDITOR
    3.     [InitializeOnLoadMethod]
    4. #endif
    5.     static void Init()
    6.     {
    7.         BestHTTP.HTTPUpdateDelegator.IsThreaded = true;
    8.     }
     
  27. Orexx

    Orexx

    Joined:
    Jun 4, 2017
    Posts:
    18
    Hi,
    can you advise what documentation to read in order to understand how to implement using this asset interaction with Twitch chat (IRC) through Websocket?
    I have never worked with networking features.
     
  28. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,351
    @Orexx

    I would recommend the plugin's documentation about its Websocket api, and the relevant Twitch one.
     
  29. cemozturk

    cemozturk

    Joined:
    Sep 27, 2015
    Posts:
    27
    Hi Tivadar,

    I have been using Besthttp since 2016.

    It'a great product, essential asset for my apps but there is a strange problem i cannot handle anymore :(

    Our application runs on Socket.io and our client is using BestHTTP to connect.

    8% percent of our users cannot connect our application via GSM Network ( 4G or 3G )

    This is the debug of Engine.io for a successful connection (you may need it) and a failed one.

    Please check successful connection debug output
    http://dgton.com/besthttp/success.txt

    And this is the failed connection debug output
    http://dgton.com/besthttp/problem.txt

    Also BestHTTP throws Status Code: 400-Bad Request Message Code 3 Message Bad Request.

    Please help us to cover 8% of our user base.

    Regards,

    Cem.

    Not :

    1. Problem users are some of GSM Network users ( Different countries different GSM Brands ) ( not wifi )
    2. There are failed connections and good connection with in same GSM Brand.
    3. Using latest version of BESTHTTP with Unity 2017 LTS ( Latest )
    4. I only use websocket connection, no long polling.
    5. If i test the connection with standart socket.io-client ( js ), the problem users' connections have no problems.
    6. Failed connections are always fail not related with timezone or location or anything else.


    Some details,

    After the
    _query: { EIO: '4', transport: 'websocket' },

    Succeeded connection returns websocket object but failed connection returns
    res: ServerResponse object.
     
    Last edited: Oct 1, 2019
  30. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,351
    @cemozturk

    The failing request has no 'upgrade' and 'connection' headers. The upgrade header is a must for the websocket protocol. Isn't your case is the first (and probably not the last) i saw where an ISP alters the request. What i can suggest to use HTTPS (WSS for websocket).
     
  31. cemozturk

    cemozturk

    Joined:
    Sep 27, 2015
    Posts:
    27
    Hi again Tivadar,

    But standard socket.io-client.js can connect w/o any hassle while BestHTTP client cannot on the same ISP ?

    Also some of the Sim Cards ( yes, sim cards ) can connect, some of cannot in same ISP if the client is BestHTTP.

    There must be another problem going on ?
     
  32. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,351
    @cemozturk

    It might be better to disable reconnection and when disconnected just use the very same function to (re)connect. So it would be something like this:
    Code (CSharp):
    1. public void Connect()
    2. {
    3.     SocketOptions options = new SocketOptions();
    4.     options.Reconnection = false;
    5.  
    6.     var manager = new SocketManager(new Uri("..."), options);
    7.  
    8.     manager.Socket.On(SocketIOEventTypes.Disconnect, OnDisconnected);
    9. }
    10.  
    11. private void OnDisconnected(Socket socket, Packet packet, object[] args)
    12. {
    13.     Connect();
    14. }
     
  33. cemozturk

    cemozturk

    Joined:
    Sep 27, 2015
    Posts:
    27
    Hi again Tivadar,

    That's how i'm using the BestHTTP Client.

    I thought we put the issue crystal clear.

    There are some ISP's, BestHTTP Socket.io client cannot upgrade but standart socket.io-client ( js ) library can.

    I have the one of these sim cards to test, i can provide whatever debug output to you.

    Tivadar, we must solve this :(
     
  34. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,351
    @cemozturk

    You can set the plugin's log level to verbose and send the logs to me:
    Code (CSharp):
    1. BestHTTP.HTTPManager.Logger.Level = BestHTTP.Logger.Loglevels.All;
    Your js client might connect with long polling, or a yet another transport, or it can be something else that triggers the ISP's logic.

    But, you can check your already linked problem.txt for the headers section:
    As you can see, parts of the websocket upgrade headers are there (sec-websocket-key, sec-websocket-version, sec-websocket-extensions) but not the `upgrade` and `connection` headers. There's no way the plugin sends an incomplete request without these headers (it sets these headers before the ones arrived). Adding to this my personal experience with ISPs deleting these headers.
    Your easiest option is to add HTTPS, so ISPs can't alter requests.
     
  35. cemozturk

    cemozturk

    Joined:
    Sep 27, 2015
    Posts:
    27
    Hi Again,

    The HTTPS solution is impossible right now to implement for our business model.

    "Your js client might connect with long polling, or a yet another transport,"

    No, intentionally i set up the JS client as BESTHTTP Options.

    I will send you to the plugin debug output as soon as possible,

    I'm sure we will pass this issue as we have passed others in previous years.

    You're great as always.

    Thank you.
     
  36. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,351
    @cemozturk

    I'm sorry, but i don't understand how your business model makes https impossible. You can get free certifactes using Let's Encrypt, but even a self-signed certficiate would do the trick to don't let anyone tamper with your requests.
     
  37. cemozturk

    cemozturk

    Joined:
    Sep 27, 2015
    Posts:
    27
    That note comes from 8 months before.

    We have tried to implement BestHTTP client for wss:// but couldn't achieve to do that because of lack of doc/example :(

    If you have a sample, we're glad to test it.

    Thank you.
     
  38. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,351
    @cemozturk

    For example my socket.io chat example connects with https://, wss://. You don't have to do too much setup, just use https:// when setting the url, and you are good to go.
     
  39. cemozturk

    cemozturk

    Joined:
    Sep 27, 2015
    Posts:
    27
    Oh i see, you don't want us to set-up a real deal SSL but just self-signed so ISP cannot alter..

    I'll give it a try,

    Thank you :)
     
  40. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,351
    @cemozturk

    You can (for example with Let's Encrypt), but you don't have to as even a self-signed one is enough to close out the ISP.
     
  41. justtime

    justtime

    Joined:
    Oct 6, 2013
    Posts:
    298
    HI there! I got this in my crasalytics
    Code (CSharp):
    1. Non-fatal Exception: java.lang.Exception: NullReferenceException : Object reference not set to an instance of an object.
    2.        at BestHTTP.HTTPConnection.ThreadFunc(BestHTTP.HTTPConnection)
    3.        at System.Threading.WaitCallback.Invoke(System.Threading.WaitCallback)
    4.        at System.Threading.ContextCallback.Invoke(System.Threading.ContextCallback)
    5.        at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext)
    6.        at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext)
    7.        at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem(System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem)
    8.        at System.Threading.ThreadPoolWorkQueue.Dispatch(System.Threading.ThreadPoolWorkQueue)
    What does it mean?
     
  42. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,351
    @justtime

    This is an issue of the plugin's threading model that i rewrote for the next big update. Unfortunately, i don't know when it will be released.
     
    justtime likes this.
  43. justtime

    justtime

    Joined:
    Oct 6, 2013
    Posts:
    298
    Hi! How can i use your asset for Application.internetReachability replacement?
     
  44. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,351
    @justtime

    Well, you could write something like this:
    Code (CSharp):
    1. var request = new HTTPRequest(new Uri("http://servertotest"), HTTPMethods.Get, (req, resp) =>
    2. {
    3.     switch (req.State)
    4.     {
    5.         // The request finished without any problem.
    6.         case HTTPRequestStates.Finished:
    7.             Debug.Log("Connected!");
    8.             break;
    9.  
    10.         // The request finished with an unexpected error. The request's Exception property may contain more info about the error.
    11.         case HTTPRequestStates.Error:
    12.             Debug.LogError("Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception"));
    13.             break;
    14.  
    15.         // The request aborted, initiated by the user.
    16.         case HTTPRequestStates.Aborted:
    17.             Debug.LogWarning("Request Aborted!");
    18.             break;
    19.  
    20.         // Connecting to the server is timed out.
    21.         case HTTPRequestStates.ConnectionTimedOut:
    22.             Debug.LogError("Connection Timed Out!");
    23.             break;
    24.  
    25.         // The request didn't finished in the given time.
    26.         case HTTPRequestStates.TimedOut:
    27.             Debug.LogError("Processing the request Timed Out!");
    28.             break;
    29.     }
    30. });
    31.  
    32. request.DisableRetry = true;
    33. request.DisableCache = true;
    34.  
    35. request.Send();
    If the request ends up in the Finished state, then it could make it to the server.
    Other cases when it couldn't.
     
    justtime likes this.
  45. t1az2z

    t1az2z

    Joined:
    Sep 30, 2015
    Posts:
    3
    Hi! I'm having some hard time figuring out where I do something wrong. I'm simply trying to download image using code from example and apply it as Texture2D for Raw Image. Here is the code
    Code (CSharp):
    1.  new HTTPRequest("my URI"), HTTPMethods.Get, (request, response)=>
    2. {
    3.     image.texture = response.DataAsTexture2D;
    4. }).Send();
    For some reason after loading, Texture field of Raw Image writes "Missing". After a second attempt of download though Texture is applied properly. Any idea how to solve this?
     
  46. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,351
    @t1az2z

    I would suggest to add some error checking, that way we might know more about what's going on:
    Code (CSharp):
    1. new HTTPRequest(new Uri("my URI"), HTTPMethods.Get, (req, resp)=>
    2. {
    3.             switch (req.State)
    4.             {
    5.                 // The request finished without any problem.
    6.                 case HTTPRequestStates.Finished:
    7.                     if (resp.IsSuccess)
    8.                     {
    9.                         image.texture = resp.DataAsTexture2D;
    10.                     }
    11.                     else
    12.                     {
    13.                         Debug.LogWarning(string.Format("Request finished Successfully, but the server sent an error. Status Code: {0}-{1} Message: {2}",
    14.                                                         resp.StatusCode,
    15.                                                         resp.Message,
    16.                                                         resp.DataAsText));
    17.                     }
    18.                     break;
    19.  
    20.                 // The request finished with an unexpected error. The request's Exception property may contain more info about the error.
    21.                 case HTTPRequestStates.Error:
    22.                     Debug.LogError("Request Finished with Error! " + (req.Exception != null ? (req.Exception.Message + "\n" + req.Exception.StackTrace) : "No Exception"));
    23.                     break;
    24.  
    25.                 // The request aborted, initiated by the user.
    26.                 case HTTPRequestStates.Aborted:
    27.                     Debug.LogWarning("Request Aborted!");
    28.                     break;
    29.  
    30.                 // Connecting to the server is timed out.
    31.                 case HTTPRequestStates.ConnectionTimedOut:
    32.                     Debug.LogError("Connection Timed Out!");
    33.                     break;
    34.  
    35.                 // The request didn't finished in the given time.
    36.                 case HTTPRequestStates.TimedOut:
    37.                     Debug.LogError("Processing the request Timed Out!");
    38.                     break;
    39.             }
    40. }).Send();
     
  47. t1az2z

    t1az2z

    Joined:
    Sep 30, 2015
    Posts:
    3
    Well... nothing happened. Console is empty and Texture is still missing.
     
  48. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,351
    @t1az2z

    You can set the plugin's log level to verbose, rerun the request and send the logs to me. You can change the log level this way:
    Code (CSharp):
    1. BestHTTP.HTTPManager.Logger.Level = BestHTTP.Logger.Loglevels.All;
     
  49. justtime

    justtime

    Joined:
    Oct 6, 2013
    Posts:
    298
    Thanks! If i want to run it in endless loop(every 5 seconds), should i somehow Dispose previous request?
     
  50. BestHTTP

    BestHTTP

    Joined:
    Sep 11, 2013
    Posts:
    1,351
    @justtime

    No, it's done by the plugin. You can use it in a fire and forget way.
     
    justtime likes this.